Visio 2003 IFilter and MTA

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.

10 thoughts on “Visio 2003 IFilter and MTA

  1. http://

    Don’t know if anyone else has had this before, but I have tried (to no avail) to get the IFilter working on all Word docs. Using the LoadIFilter method seems to work fine on more than 90-95% of all docs on my pc.
    <br>
    <br>I then used the same example above by creating a type from the CLSID, but the problem persists. The error thrown is &quot;Catastrophic failure&quot; as soon as the Load method is called. I also tried spawning a seperate thread and setting it to STA.
    <br>
    <br>I haven’t found any information about this problem anywhere on the web. Do you think it is the way the filter is initialized or is it actually a problem with Microsoft’s Offilt.dll

  2. Rob Garrett

    Raldo,
    <br> I managed to get the IFilter to work for office documents, I just ran into problems with IFilter for Visio. I used the same code as above. If you’re getting a catastophic error then I would guess that there is a problem with you installation of the office IFilter, or even office itself. Try your code on another machine (if possible) and a new installation of office. I would be happy to look at your code if you emailed it to me.

  3. http://

    Rob,
    <br>Thanks for the offer to help. I’ve got quite of bit of other code to finalise and then I may send you sample if I haven’t managed to solve it myself.

  4. http://

    Hi Rob
    <br>
    <br>I have made some interesting discoveries with regard to the IFilter and would like to have your opinion. Microsoft provides a IFilter testing framework provided with the Platform SDK <a target=”_new” href=”http://msdn.microsoft.com/library/default.asp?url=/library/en-us/indexsrv/html/ixufilt_96n9.asp”>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/indexsrv/html/ixufilt_96n9.asp</a&gt;
    <br>
    <br>When running this test on some of my word docs it always fails on the same set of docs that fail in my own code. Through this I discovered (assume) that nothing is wrong with my code. To take it further, I installed the latest Windows Desktop Search on a test machine and run these same test on the same set of docs and all worked fine. (I believe this testing framework uses LoadIFilter).
    <br>
    <br>This lead me to think that Microsoft’s default IFilter shipped with Windows 2000/XP etc cannot filter all docs. That’s why Microsof are shipping updated IFilter’s with their Desktop Search Tool.
    <br>
    <br>My actual question is: I use the LoadIFilter through platform Invoke to determine which IFilter to use. I see you prefer to get the type based on the doc CLSID and create an IFilter from that. Is their any particular reason why you prefer using it this way?

  5. http://

    Sorry, didn’t actually go over your code again. I see you do use LoadIFilter if the CreateInstance call failed. But still, why is this better and is it better?
    <br>
    <br>I would have thought for it to be the other way around?

  6. http://

    Hi
    <br>
    <br>I tried the your method and got this error.
    <br>
    <br>System.Runtime.InteropServices.COMException (0x8000FFFF): Catastrophic failure
    <br> at System.Runtime.InteropServices.UCOMIPersistFile.Load(String pszFileName, Int32 dwMode)
    <br>
    <br>I also get this catastrophic failure with the Microsoft IFilter testing framework for the test set that doesn’t want to filter. This means that their could hopefully be a workaround for this (which I have been unable to find), or I have to write my own IFilter like Microsoft did for MSN Desktop Search, or wait until Microsoft provides a free update I can ship with our product.
    <br>

  7. Rob Garrett

    Raldo,
    <br> Thanks for the numerous comments that you posted, Sorry if I have been a little behind in getting back to you.
    <br>
    <br>From the nature of your posts it sounds that you have a lot more knowledge on this subject than I. found that a lot of experimenting was required to get IFilters to work correctly in custom code.
    <br>
    <br>With regard to your word docs, if the desktop framework gives you an error then it can either mean that the IFilter is broken, or that your word doc has something funky, which prevents it opening. I found that documents with any form of security set on them would cause problems – but this generally meant that the load method came back with E_FAIL, not a catastrophic error. If I can find some time I could check out your documents and find out why my code does not work with them.
    <br>
    <br>BTW, there are a ton more comments to my other post about IFilters here: <a target=”_new” href=”http://robgarrett.com/Blogs/software/archive/2005/01/11/442.aspx”>http://robgarrett.com/Blogs/software/archive/2005/01/11/442.aspx</a&gt;
    <br>
    <br>I’m not sure how much more time I can put into the IFilter problems – I essentially wrote some code for a company I was working for a while ago – I chalked them up to being unreliable at best. As with all 3rd party libraries, your code stability is at the mercy of the implementation of the IFilters you use, which concerned me. I’ll do my best to assist you.

  8. http://

    Hi.
    <br>I am trying to extract text from Excel documents using Microsoft IFilter (OFFFilt.dll)
    <br>
    <br>My problem is with the cells order – the extracted text is not in the order it appears in spreadsheet (down than over / over than down), I think it is related to the time the cells were created/modified.
    <br>
    <br>Can I control that extraction order?
    <br>Thanx alon.

  9. http://

    Hi,

    I tried to extract properties of MS office 2003 document using IFitler(offfilt.dll). But never luck. It only extracts the text content. While properties of MS office 2007 document can be extracted using IFIlter(offfiltx.dll).

    Is it possible to extract properties of MS office 2003 document?

    Thanks.

Comments are closed.