My problem is this:
If Autodesk Inventor is not running, my app (console app) creates a new instance with Activator.CreateInstance(InventorType);
and uses it as a COM object. When my app does not quit Inventor but leaves it open and the user later quits it by hand there is still a process inventor.exe running in TaskManager which can only be killed in TaskManager.
Curiously the problem only arises when these two things are combined. Whenever my app quits Inventor with InventorApp.Quit();
it is closed properly and there is no process left open.
If my app starts Inventor with Process.Start(..);
or the user starts Inventor before starting the app and then my app grabs Inventor with Marshal.GetActiveObject(ProgId);
there is no problem no matter if the app or the user quits Inventor.
If my app starts Inventor with Activator.CreateInstance(InventorType);
then leaves Inventor open, the app is closed and then restarted, it grabs Inventor with Marshal.GetActiveObject(..);
and then quits Inventor via InventorApp.Quit();
there is no problem.
So, the problem with the left open process only arises in this specific combination:
- start Inventor via
Activator.CreateInstance(InventorType);
- the user quits Inventor by hand
The left open process is not in the Running Object Table anymore so it can't be handled as a COM object anymore and it has no visible UI, which means it can only be killed in TaskManager.
Using the 'bad combination' as described I even tried to call GC.WaitForPendingFinalizers(); GC.Collect();
several times (I know this is bad but I am just trying everything) in different combinations and before and/or after Marshal.ReleaseComObject(invApp); Marshal.FinalReleaseComObject(invApp);
. I even tried a minimal app which literally does nothing else. See below for the code.
So, what is Activator.CreateInstance(InventorType);
doing that is causing this? Is there any way to prevent this? Or is this a problem specific to Inventor?
Minimal app example:
Inventor.Application invApp = null;
string ProgId = "Inventor.Application";
try
{
invApp = (Inventor.Application)Marshal.GetActiveObject(ProgId);
}
catch (Exception e1)
{
try
{
Type InventorType = Type.GetTypeFromProgID(ProgId);
invApp = (Inventor.Application)Activator.CreateInstance(InventorType);
}
catch (Exception e2)
{
Console.WriteLine(e1);
Console.WriteLine(e2);
}
}
invApp = invApp as Inventor.Application;
invApp.Visible = true;
Console.Write("Quit Inventor? (y/n) ");
string quit = Console.ReadLine();
if (quit == "y")
{
invApp.Quit();
}
// desperately trying to release the COM object ...
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
if (invApp != null)
{
Marshal.ReleaseComObject(invApp);
Marshal.FinalReleaseComObject(invApp);
}
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
if (invApp != null)
{
Marshal.ReleaseComObject(invApp);
Marshal.FinalReleaseComObject(invApp);
}
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
invApp = null;