1

I am creating an app in c# that instantiates a COM object of the commercial software StressCheck.

I instantiate this in a wrapper class that implements the IDisposable interface. I dispose of it by calling theComInstance.Close() method within the wrapper class' Dispose() method.

There are two floating licenses served by the IT department. The IT department is responsible for managing the licenses.

Everything seems to work as intended.

My problem is that; when I am in debug mode, if I press "stop", the app will not go through the Dispose() method and therefore will not properly close the COM object and release the license.

Sometimes, I will go for hours before the license is released. This blocks my development of the tool.

I tried killing the stresscheck.exe app from the task manager but this does not seem to release the license. I presume the license needs to be released from within the COM's close() method.

I thought of maybe writing a Powershell script to try to get back the handle of the COM instance (out of proc) and invoke this method. I don't know if this is feasible (nor how to do it).

Is there another way to achieve this? Marshalling? something in the dispose method that I should do in order for the GC to release the license?

I don't have any experience managing COM objects so any help is greatly appreciated.

Here's the wrapper class with the dispose pattern that I used:

using System;
using System.Runtime.InteropServices;

namespace Infrastructure.Services.StressCheck
{
    public class StressCheckEngine: IDisposable
    {
        private protected ESRD.StressCheck.Core.Application ComObject;

        // To detect redundant calls
        private bool _disposed;

        public StressCheckEngine()
        { 
            ComObject = new ESRD.StressCheck.Core.Application();
        }

        ~StressCheckEngine() => Dispose(false);

        // Public implementation of Dispose pattern callable by consumers.
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        // Protected implementation of Dispose pattern.
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    if (ComObject != null && Marshal.IsComObject(ComObject))
                    {
                        try
                        {
                            ComObject.Close();
                            Marshal.FinalReleaseComObject(ComObject);
                        }
                        catch (COMException err)
                        {
                            throw err;
                        }
                        catch (Exception err)
                        {
                            throw err;
                        }
                        finally
                        {
                            ComObject = null;
                        }
                    }
                }
                _disposed = true;
            }
        }
    }
}
Khaoz-07
  • 11
  • 4
  • You left us no code to help you with, but I think you'll want to use [Marshal.ReleaseComObject(Object) Method](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.releasecomobject) – Theo Oct 06 '22 at 10:31
  • Hi thanks for the comment, I didn't have the code in front of me when I wrote the question, I have added the snippet that handles the disposal. Maybe I'm doing something wrong, I had used Marshal.FinalReleaseComObject(ComObject) instead. – Khaoz-07 Oct 06 '22 at 14:51

0 Answers0