And Now For Something Completely Different

We interupt this blog’s coverage of OOPSLA with a quick observation & question related to development…

I’m hacking around writing a Word 2003 SmartTag in C# (more on the why later). I wanted my recognizer to be document-dependent – i.e. depending on some custom document properties, I wanted to change what gets recognized. A little digging reveils that there is no way (that I could find) to access the Word object model from the recognizer! The Recognize (and Recognize2) method receives strings as parameters, but it doesn’t receive an app-specific target object. This is unlike the Smart Tag Action‘s InvokeVerb (and InvokeVerb2) method which receives a Range object (from which you can navigate to the containing document, application and window) when running inside of Word. Bummer.

I think the reason for this is that the recognizer appears to run on a background thread while the action appears to run on the main app thread. Furthermore, both threads are STA apartment threaded, so if I can access the COM-based object model from the action thread, I can’t access it directly from the recognizer thread. I actually hacked up an add-in to provide the ActiveDocument to the recognizer thru a backchannel and it hangs Word on shutdown. I thought there might be an issue releasing the COM reference, but explicitly releasing it crashes the recognizer the next time it accesses the ActiveDocument.

So I’ve come to the conclusion that I somehow need to marshal this call from the background thread to the main app thread the action and addin are runing on (I did verify that both of those run on the same thread). The question is, what’s the best way to do that given that I’m writing this in C#? I thought I might use a system similar to Windows Form’s Control.Invoke(…), but it turns out that works by sending windows messages which isn’t particularly feasible for my problem. So now I’m thinking I have pass the ActiveDocument reference to the background thread using CoMarshalInterface. Or I might be able to use RemotingServices.Marshal() instead.

Anyone have any ideas? If so, leave a comment or drop me a line.

Comments:

Hi pierson, If we want smart tags to be attached to a specific document template, we need to configure the expansion pack which we will be attaching to the document template. stating this, there will be a document template associated to a specific expansion pack manifest file. We will be building the smart tag dll in the usual way, but you will need to use XML expansion pack and the XML expansion manifest file to deploy that smart tag. Have a look at the XML Expansion pack schema, for configuring smart tag deployment, in Microsoft Office 2003 Smart document SDK. Cheers, Babu
Hi Pierson, Using custom properties is a tricky one, but we can add required data to registry using the expansion pack manifest file (schema already available to do this) and use that data in your smart tag. This can also be document specific, because you are doing this at a expansion pack level. Cheers, Babu