zondag 12 oktober 2008

MOSS: Label policy – how does it really work

The policies in MOSS allow you to add some document management functionality to MOSS. For example you can specify a label policy to ensure a certain label is always added to your document. But how does this work?

When saving a document to a document library, or when creating a new document from a document library the server adds the policy information to the file. Note, the file must be Word 2007 docx file (2003 doc file should also work, I will test this). The following information is added to the docx.

In the customXml folder of the unzipped word document we find the file item2.xml:

<?mso-contentType?>
<p:Policy xmlns:p="office.server.policy" id="" local="true">
<p:Name>Document</p:Name>
<p:Description>Mypolicy desc</p:Description>
<p:Statement>Label mypolicy</p:Statement>
<p:PolicyItems>
<p:PolicyItem featureId="Microsoft.Office.RecordsManagement.PolicyFeatures.PolicyLabel">
<p:Name>Labels</p:Name>
<p:Description>Generates labels that can be inserted in Microsoft Office documents to ensure that document properties or other important information are included when documents are printed. Labels can also be used to search for documents.</p:Description>
<p:CustomData>
<label>
<event type="save"/>
<event type="print"/>
<segment type="literal">MyPolicy</segment>
</label>
</p:CustomData>
</p:PolicyItem>
</p:PolicyItems>
</p:Policy>

and item5.xml



<?xml version="1.0" encoding="utf-8"?>
<p:properties xmlns:p="http://schemas.microsoft.com/office/2006/metadata/properties" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<documentManagement>
<DLCPolicyLabelLock xmlns="4d54d727-23fa-4efe-b6bd-38291cb8f05e" xsi:nil="true"/>
<DLCPolicyLabelClientValue xmlns="4d54d727-23fa-4efe-b6bd-38291cb8f05e">MyPolicy</DLCPolicyLabelClientValue>
<DLCPolicyLabelValue xmlns="4d54d727-23fa-4efe-b6bd-38291cb8f05e">MyPolicy</DLCPolicyLabelValue>
</documentManagement>
</p:properties>

So the policy rules are included in the document it self.  The policy I added was myPolicy. Note the label policy does not work with the watermark functionality :(. I guess you can write a “Watermark” policy using the same strategy.

vrijdag 3 oktober 2008

Quick TIP: Skip folders Windows desktop search

We have a lot of documents on file shares. I use windows desktop search to index the file share. This works ok, but I also was getting a lot of older versions of documents. These documents are always stored in a "archive" directory, so I cracked open the help and found:

searchterm NOT in:archive


Instead of "in:" you can also use "foldername:". Works likes a charm!

zondag 10 augustus 2008

Windows Update fails

I find Windows update on of the lesser stable parts of the Windows OS (XP pro). On a fresh installation my windows update failed with the following error (%windir%\Windowsupdate.log):

FATAL: Error: 0x80004002. wuauclt handler: failed to spawn COM server


Google to the rescue. The following fixed my problem (from a command prompt):

net stop wuauserv
regsvr32 wuapi.dll
regsvr32 wuaueng1.dll
regsvr32 wuaueng.dll
regsvr32 wucltui.dll
regsvr32 wups2.dll
regsvr32 wups.dll
regsvr32 wuweb.dll
net start wuauserv


Some extra info: http://support.microsoft.com/kb/910359.

donderdag 7 augustus 2008

Unable to connect to data.beta.mssds.com

While doing some tests on SQL Server Data Services (SSDS) at work I was unable to run my samples I created at home. At home they worked perfectly. The hostname could not be found for some dark reason. I was able to get the IP from a web based DNS lookup (http://www.zoneedit.com/lookup.html) and tried to get the REST and SOAP API to work with the IP address. The SOAP API works, but the rest API needs a valid hostname. The error included a nice call stack :), definitely some WCF love there.

The server encountered an error processing the request. The exception message is 'IsEqual: invalid host'. See server logs for more details. The exception stack trace is:
at Microsoft.Stratus.Common.Assert.IsEqual[T](T actual, T expected, String format, Object[] args)
at Microsoft.Stratus.Service.Metrics.RESTMessageHelper.GetAuthorityIdContainerIdFromRequest(Message& request, String& authorityId, String& containerId)
at Microsoft.Stratus.Service.Metrics.MetricsManager.CollectMetricsAfterReceiveRequest(Message& request)
at Microsoft.Stratus.Service.Metrics.SitkaMessageInspector.AfterReceiveRequest(Message& request, IClientChannel channel, InstanceContext instanceContext)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.AfterReceiveRequestCore(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)



Adding the host to my local host file solved the problem.

maandag 14 april 2008

Send mail with telnet over SMTP

How to test your SMTP server? Use telnet. Open up a command prompt and telnet to your smtp server: TELNET server 25, where 25 is the default SMTP port.
image
220 ...
HELO [your name, can be anything]250 ...
MAIL from: [your email address, can be anything]250 ... Sender OK
RCPT to: [destination email address]250 ...
RCPT to: [destination email address]
250 ...
DATA
[type the message body including mail headers, end with enter . enter]250 Queued mail for delivery



The bold italic lines are the lines you have to type. Note, telnet sends every character you type directly to the server, so typo's are not allowed! I also a program called TCP, that does the same as telnet but only sends data after a return, so you can use that backspace!

IIS SMTP LDAP routing, WTF

Windows 2003 Server has a SMTP server, hosted in IIS6. This SMTP server has a feature, LDAP routing.

image

The documentation for this feature is pretty minimal:

With the LDAP Routing tab, you can configure the SMTP service so that it will consult an LDAP server to resolve senders and recipients. For example, you can use Active Directory directory service as an LDAP server, and use Active Directory Users and Computers to create a group mailing list that is automatically expanded on the Simple Mail Transfer Protocol (SMTP) virtual server.

Resolve sender and recipients?? How, when, based on what attribute? And what if not resolved? And what if the user is resolved? Can it be used for SMTP authorization?

Well one thing it can do is provide AD integration, so mailing groups can be created. See this tread http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Server/2003_Server/Q_21938977.html with the interesting title "How does LDAP Routing (for the SMTP service) work? In particular together with AD"

I someone knows some decent documentation, please let me know!

vrijdag 4 april 2008

Communicating with a PERL web service

Sometimes you have communicate with a existing web services, and there is just no documentation or WSDL. In my case the web service was written in Perl. You can take these steps to try to generate a decent proxy for the web service.

First sniff the network so you have the exact request and response.

Sample request:

POST /PERL.asmx HTTP/1.1
SOAPAction : PERLWebserviceMethods#SomeMethod
Content-Type : text/xml
Host : localhost:2353
Content-Length : 544
Connection : Keep-Alive

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SomeMethod xmlns="PERLWebserviceMethods">
<ipaddress xsi:type="xsd:string">86.87.60.177</ipaddress>
</SomeMethod>
</soap:Body>
</soap:Envelope>


Sample Response (body):


<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SomeMethodResponse xmlns="PERLWebserviceMethods">
<foo xsi:type="xsd:string">blabla</foo>
<bar xsi:type="xsd:string">1</bar>
</SomeMethodResponse>
</soap:Body>
</soap:Envelope>

Then we craft a web service mimicking the PERL web service.

[WebService(Namespace = "PERLWebserviceMethods")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class PERLWebservice : System.Web.Services.WebService
{
[WebMethod]
[SoapDocumentMethod(ResponseNamespace = "PERLWebserviceMethods",
ResponseElementName = "SomeMethodResponse",
ParameterStyle = SoapParameterStyle.Bare,
Action = "PERLWebserviceMethods#SomeMethod")]
public SomeMethodResponse SomeMethod(SomeMethod ipaddress)
{
SomeMethodResponse res = new SomeMethodResponse() { foo = "blabla", bar = "1" };
return res;
}
}

[XmlRoot("SomeMethodResponse")]
public class SomeMethodResponse
{
public string foo { get; set; }
public string bar { get; set; }
}

[XmlRoot("SomeMethod")]
public class SomeMethod
{
public string ipaddress { get; set; }
}


Now we can generate a proxy with the 'normal' tooling, generate a WSDL, and connect to the PERL web service. The trick is in using the SoapParameterStyle.Bare. This gives al lot more flexibility in crafting the resulting soap.

When this method fails you can go the WCF route and use the available hooks in WCF to consume the web services.

First post

This will be a technical blog where I will share my experiences as a .Net software developer.