I have come across this before and Paul B is really right. It depends on whether you are calling Powerpoint OM from the main thread (i.e. This_AddIn ) or not. If you, ppt should not throw these exceptions. However, if you call ppt from another thread, you must implement IMessageFilter to effectively manage these messages with message pump errors, since ppt prioritizes the main thread calls for OM over calls from other threads, hence rejecting the call.
There is another caveat that requires additional boiler plate code to handle additional COMException , such as 0x800AC472 (VBA_E_IGNORE) . The following is an example.
So, the complete solution is to implement IMessageFilter and use something like sepp2k in which you can wrap your OM calls in order to handle other types of COMException that might be thrown.
So, for wrapping code like this:
private void TryUntilSuccess(Action action) { bool success = false; while (!success) { try { action(); success = true; } catch (System.Runtime.InteropServices.COMException e) { if ((e.ErrorCode & 0xFFFF) == 0xC472) { // Excel is busy Thread.Sleep(500); // Wait, and... success = false; // ...try again } else { // Re-throw! throw e; } } } }
which you could call using lamdas as follows:
TryUntilSuccess(() => { RegisterFilter(); // register this thread for IMessageFilter use ppt_app.DoSomething(); UnRegisterFilter(); // unregister this thread for IMessageFilter use };)
The reason for this bi-directional approach is that the IMessageFilter strategy is more efficient than throwing exceptions and there will be more time than it will not be able to process busy messages coming from the application. However, at another time you will have to handle the exceptions, so you need to do both ...
See here Implementing IMessageFilter , which Includes Wrappers
Hth!
Pat mustard
source share