Adding CustomDocumentProperties to Office Documents

In working through adding custom document properties to Office docs I ran in to several problems that took me a while (and a hint from this question at StackOverflow.com) to figure out.  I posted a short version of my solution there, but wanted to document the full process here.

The first problem I ran into was dealing with the dynamic nature of Office code. Writing what seems to be the obvious initializers doesn’t work as one would expect. The following code won’t even compile:

Office.DocumentProperties custProps = this.CustomDocumentProperties;

A cast is required here:

var custProps = (Office.DocumentProperties)this.CustomDocumentProperties;

After that I tried the obvious thing (this code is within the ThisWorkbook_Startup method, so “this” refers to an Excel document, in this case):

var custProps = (Office.DocumentProperties)this.CustomDocumentProperties; custProps.Add( "AProperty", false, AStringPropertyVariable.GetType() , AStringPropertyVariable );

Essentially, I’m saying “Call the Add() method and provide the System.Type of the System.String Type for the Type parameter”.  This triggers a COMException: Type mismatch.

Looking at the Microsoft Support article linked to in the previous answers to this question, it became apparent that the Type parameter of the Add() method requires an Office-specific type, so I replaced the 2nd line above with:

custProps.Add( "AProperty", false, MsoDocProperties.msoPropertyTypeString, AStringProperty );

and setting the custom property worked great. Because it’s a CustomDocumentProperty Office will add the custom type without difficulty, but I only want to add it if it doesn’t already exist but when the item of the CustomDocumentProperties collection doesn’t exist there’s no way to know without catching a System.ArgumentException, so the final, full solution for me ends up as:

Office.DocumentProperties custProps = (Office.DocumentProperties)this.CustomDocumentProperties;
try {
    string aPropValue = custProps["AProperty"].Value;
} catch ( System.ArgumentException ex ) {
     custProps.Add( "AProperty", false, MsoDocProperties.msoPropertyTypeString, AStringVariable );
}

Interestingly enough, while looking for a little additional background on the var keyword in relationship to this post I stumbled on Scott Hanselman’s post (strangely enough also related to DocumentProperties in Word and the unsuitability of C# 3.0 for that purpose). In it he points to a different MSDN article (the VS 2010 version of that article is essentially the same, with the exception of the note regarding host controls – not relevant in the more up-t-date Office and VS versions) that he says doesn’t work properly, and while I didn’t actually run the code from that article it’s using pretty much the same concepts that are working for me here. I would be curious to know which part wasn’t working – perhaps it didn’t work very well in Office 2003 or 2008 (I’m using Office and VS 2010 and C# 4).