Adwaenyth Adwaenyth - 27 days ago 7
C# Question

How to properly Dispose a COM Object if the COM application crashed?

The problem:

I've got to call an application via COM interop from a C# .NET application. I've written a wrapper class to handle the COM stuff and all that works nice and shiny.

public sealed class ComWrapper : IDisposable
{
private Application comApplication = new Application(); // Referenced COM assembly.
private bool disposed;

// Several methods to interact with the com application.

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
if(disposed)
return;

try
{
if(comApplication != null && Marshal.IsComObject(comApplication));
Marshal.ReleaseComObject(comApplication);
}
finally
{
comApplication = null;
}

disposed = true;
}
}


I can call the app, use its methods and all works as long as the COM app runs fine.

However, should the application crash (which it does sometimes when the database connection is lost) the executable will remain loaded. In Process Explorer I can see the application's process under
svchost.exe
with a
werfault.exe
process even if I call the garbage collector manually after catching a
COMException
.

catch(COMException)
{
app.Dispose();
app = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}


How can I properly Dispose of a COM object in a way that it will also properly exit the application and close the process even if that COM application has crashed? I thought about determining the process ID of said application and using
Process.Kill()
but that seems a little ugly to me. So what would be the appropriate way of terminating and freeing the resources of the crashed app?

Answer Source

If this is an external COM server you can do nothing from the client.

From your side, you can Do nothing else than you are already doing. Dispose the COM object and you are done. If the COM application is still alive, than there are some error handlers that causes the application not to close. Maybe it shows an error message.

But I am wondering, that you see a SVCHOST process. Is this a service? If so the SCM should manage the failure. COM usually host external servers inside a SVCHOST.EXE.

So maybe you didn't provide enough information about the kind of external process that is used.

BTW: Calling GC.Collect is never wise... ;)