私の問題は次のとおりです。Autodesk Inventor が実行されていない場合、私のアプリ (コンソール アプリ) は新しいインスタンスを作成し、Activator.CreateInstance(InventorType);
それを COM オブジェクトとして使用します。アプリが Inventor を終了せずに開いたままにし、後でユーザーが手動で終了した場合、タスク マネージャーでのみ実行されているプロセスのInventor.exeがタスク マネージャーでのみ強制終了されます。興味深いことに、この問題は、これら 2 つのことが組み合わされた場合にのみ発生します。アプリがInventorApp.Quit();
適切に閉じられた状態で Inventor を終了するたびに、開いたままのプロセスはありません。
アプリが Inventor を起動するProcess.Start(..);
か、ユーザーがアプリを起動する前に Inventor を起動し、アプリが Inventor を取得しMarshal.GetActiveObject(ProgId);
た場合、アプリまたはユーザーが Inventor を終了しても問題はありません。
アプリで Inventor を起動してから Inventor をActivator.CreateInstance(InventorType);
開いたままにしておくと、アプリを閉じてから再起動するMarshal.GetActiveObject(..);
と、Inventor が取得されて Inventor が終了しInventorApp.Quit();
、問題はありません。
そのため、左に開いたプロセスの問題は、次の特定の組み合わせでのみ発生します。
- からInventorを起動します
Activator.CreateInstance(InventorType);
- ユーザが手で Inventor を終了する
開いたままのプロセスは実行中のオブジェクト テーブルに存在しないため、COM オブジェクトとして処理できなくなり、UI が表示されなくなります。つまり、タスク マネージャーでのみ強制終了できます。
説明されているように「悪い組み合わせ」を使用して、さまざまな組み合わせと before および/または after で何度か呼び出しを試みましたGC.WaitForPendingFinalizers(); GC.Collect();
(これが悪いことはわかっていますが、すべてを試しているだけです) 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;