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.
private static void LoadIFilterFromSource(string fileName, ref IFilter filter)
{
// Get the extension.
string ext = Path.GetExtension(fileName);
if (null == ext || 0 == ext.Length)
throw new FilterException(“File does not have a known extension!”);
// Get the CLSID of the filter by extension.
string clsID = GetFilterCLSID(ext);
if (null != clsID && clsID.Length > 0)
{
// Get filter instance.
try
{
Type t = Type.GetTypeFromCLSID(new Guid(clsID));
if (null != t)
{
object filtObj = Activator.CreateInstance(t);
filter = (IFilter) filtObj;
// ^^^^^ Cast Exception thrown here!
}
}
catch (Exception ex)
{
throw new FilterException(“Failed to create IFilter instance!”, ex);
}
}
// Did we load the filter?
if (null == filter)
{
// No, attempt to load via COM.
try
{
IUnknown outer = null;
LoadIFilter(fileName, ref outer, ref filter);
}
catch (COMException ex)
{
throw new FilterException(“Failed to create IFilter instance!”, ex);
}
}
}
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.
HKLMSOFTWAREClassesCLSID{FAEA5B46-761B-400E-B53E-E805A97A543E}InprocServer32ThreadingModel.
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.

