0

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?

1
  • This is just one of the liabilities of out-of-process COM and one of the reasons why it rarely gets used. It did help make Java a significant winner in the middleware wars of the late 90s. The OS has a garbage collector for orphaned servers, it is not in a terrible hurry to kill them off. At least 10 minutes afaik. It doesn't always work, for reasons that were never obvious to me, Office apps don't get killed-off for example. Commented Sep 21, 2017 at 11:09

1 Answer 1

2

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... ;)

Sign up to request clarification or add additional context in comments.

1 Comment

Actually it's a normal windows application, not a service. If you launch it via COM it seems to be configured to start under SVCHOST. (I think it is not the very best of programs ever designed, but sadly I'm stuck with it). But it seems I've figured out what happens... If the app hard crashes, it creates another process of itself that is orphaned... On first look the handles were so similar I didn't notice the difference. So I guess I'm stuck with cleaning up via Process.Kill otherwise it won't start up again because it exchanges messages with all instances and that orphaned one then blocks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.