7

From msdn it seems that IMessageFilter doesn't handle all exceptions, for example, at some points, office applications 'suspend' their object model, at which point it cannot be invoked and throws: 0x800AC472 (VBA_E_IGNORE)

In order to get around this, you have to put your call in a loop and wait for it to succeed:

while(true)
{
    try
    {
        office_app.DoSomething();
        break;
    }
    catch(COMException ce)
    {
        LOG(ce.Message);
    }
}

My question is: if this boiler-plate code is necessary for each call to the office app's object model, is there any point in implementing IMessageFilter?

Pat Mustard
  • 1,852
  • 9
  • 31
  • 58

1 Answers1

8

Yes, the two mechanisms are independent. IMessageFilter is a general COM mechanism to deal with COM servers that have gone catatonic and won't handle a call for 60 seconds. The VBE_E_IGNORE error is highly specific to Excel and happens when it gets in a state where the property browser is temporarily disabled. Think of it as a modal state, intentionally turned on when Excel needs to perform a critical operation that must complete before it can handle out-of-process calls again. A lock if you will. It is not associated with time, like IMessageFilter, but purely by execution state. Geoff Darst of the VSTO team gives some background info in this MSDN forums thread.

Having to write these kind of retry loops is horrible of course. Given that it is an execution state issue and assuming that you are doing interop with Excel without the user also operating the program, there ought to be a way to sail around the problem. If you are pummeling Excel from a worker thread in your program then do consider reviewing the interaction between threads in your code to make sure you don't create a case where the threads are issuing Excel calls at roughly the same time.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks, Hans. Your points are indeed useful. I have taken great care to make sure two threads don't hammer excel with requests at the same time but the boiler-plate code required to force these retries does irk me a touch. I guess I could just remove the message filter altogether if each call is in a retry loop since all exceptions would be caught, if in a less efficient way. – Pat Mustard Feb 01 '13 at 09:20