I recently had a problem instantiating the
Visio 2003 IFilter from C#....
The following code instantiates an IFilter using COM Interop. The CLSID
is obtained from the registry (method excluded for brevity) and then used to
obtain the COM object type, the activator then instantiates the object from
the type. I tested the code from a console C# application and it works
great. The CLSID is correctly obtained from the registry for a given
VSD extension and then the COM object is instantiated by the activator.
When I call this same code from a WinForm application the method throws
an invalid cast exception when casting an activated object to an
IFilter. Stepping through with the debugger shows me that the CLSID is
obtained correctly, the type is returned from Type.GetTypeFromCLSID,
and the call to the activator also succeeds.
I read somewhere that the threading model for the COM component matters when calling from a multi threaded environment. So, I made sure the calling code to my method is running in a Single-Threaded-Apartment (STA) thread. This change from Multi threaded Apartment (MTA) to STA fixed the same problem with the
Adobe PDF IFilter, but did nothing for the Visio IFilter.
I had just about given up when I decided to check the threading model in the registry. I noticed that the PDF IFilter's threading model is set to Apartment, whereas the Visio threading model is blank. Setting the following registry REG_SZ value to Apartment fixes the problem with Visio also.
HKLM\SOFTWARE\Classes\CLSID\{FAEA5B46-761B-400E-B53E-E805A97A543E}\InprocServer32\ThreadingModel.
I'm not sure if this is an problem with the installation of the Visio IFilter or intended. When I reinstalled the IFilter the threading model was set back to empty. It's not an elegant solution, but it seems to work.