Search code examples
.netcomms-officevsto

How to check if a COM object still exists


I basically understand how managed RCW objects wrap COM objects in .NET. My question is what happens when the COM object ceases to exist. I know that the RCW object increases the reference count so the COM object should not be released as long as the RCW object is alive. But what if the COM object is deleted from a user perspective?

  • Say I have a shape in PowerPoint, a worksheet in Excel or a Word paragraph. My application creates a reference and keeps it for some time.

  • The user may now delete the PowerPoint slide, close the Excel file or delete the Word paragraph. What's the right way to detect this?

Trying it out suggests that the COM object throws a COMException with error code 0x80004005 saying object does not exist when accessing any property.

But I am wondering: Is this a reliable and fail-safe approach? Will the COM object really stay around with the RCW object or may Office remove it from memory? In that case, isn't it dangerous to use the dangling reference and is there a better approach?


Solution

  • What you are doing is inherently risky. Using Automation while the user is interacting with the Office program is tricky and you have to code carefully. The specific COM object does not get deleted, they are reference-counted and you are holding a reference on it. But when the user removes it from the document then only an object in memory remains, it is not part of the document anymore of course.

    Trying to dereference members of that object is indeed pretty likely to fail. The Office program itself is likely to have removed any internal reference that the object keeps. You are getting a very crappy exception for it, that is not unusual either, 0x80004005 is E_FAIL, "Unspecified error". That can hardly be called an error, it is but a teacher's grade for the quality of the error reporting.

    Ideally you'd get an event that tells you to drop your object reference. Pretty hard to come by, Office apps are not that chatty. Best thing to do is not hold a reference at all but find it back whenever you need it. If that's not practical then you've got try/catch-em-all as the ultimate fallback hack.