0

私の問題は次のとおりです。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();、問題はありません。

そのため、左に開いたプロセスの問題は、次の特定の組み合わせでのみ発生します。

  1. からInventorを起動しますActivator.CreateInstance(InventorType);
  2. ユーザが手で 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;
4

1 に答える 1