我的问题是:如果 Autodesk Inventor 没有运行,我的应用程序(控制台应用程序)会创建一个新实例Activator.CreateInstance(InventorType);
并将其用作 COM 对象。当我的应用程序没有退出 Inventor 而是让它保持打开状态并且用户稍后手动退出它时,TaskManager 中仍然有一个进程inventor.exe正在运行,它只能在 TaskManager 中被杀死。奇怪的是,只有将这两件事结合起来时,才会出现问题。每当我的应用程序退出 Inventor 并InventorApp.Quit();
正确关闭并且没有任何进程处于打开状态时。
如果我的应用程序使用 Inventor 启动Process.Start(..);
或用户在启动应用程序之前启动 Inventor,然后我的应用程序使用 Inventor 抓取,Marshal.GetActiveObject(ProgId);
则无论应用程序或用户退出 Inventor 都没有问题。
如果我的应用程序使用 Inventor 启动Activator.CreateInstance(InventorType);
然后保持 Inventor 打开,应用程序关闭然后重新启动,它使用 Inventor 抓取Marshal.GetActiveObject(..);
然后退出 Inventor,InventorApp.Quit();
没有问题。
所以,左开进程的问题只出现在这个特定的组合中:
- 通过以下方式启动 Inventor
Activator.CreateInstance(InventorType);
- 用户手动退出 Inventor
左打开进程不再在运行对象表中,因此它不能再作为 COM 对象处理,并且它没有可见的 UI,这意味着它只能在 TaskManager 中被杀死。
使用所描述的“错误组合”,我什至尝试以GC.WaitForPendingFinalizers(); GC.Collect();
不同的组合以及 before 和/或 after 多次调用(我知道这很糟糕,但我只是在尝试一切)Marshal.ReleaseComObject(invApp); Marshal.FinalReleaseComObject(invApp);
。我什至尝试了一个最小的应用程序,它实际上什么都不做。请参阅下面的代码。
那么,是Activator.CreateInstance(InventorType);
什么导致了这种情况?有什么办法可以防止这种情况发生吗?或者这是 Inventor 特有的问题?
最小的应用程序示例:
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;