1

ここでの私の目的は、C# を使用してサードパーティ アプリケーションを制御することです。サードパーティ アプリケーションは、COM 参照によって制御できます。

単純なコンソール アプリケーションに参照を追加しましたが、クラスとメソッドに問題はありません。

次の行は、サードパーティ アプリケーションの起動をトリガーします。それは何をしますか。Taskmanager/Processes (mfl32.exe) で、問題なくそこに座っているのを見ることができます。

MFL32.Application mfl = new MFL32.Application();

コンソール アプリケーションが終了しても、mfl32.exe はプロセス リストに残っています。これは、閉じるための呼び出しを行っていないため、当然のことです。次に、次の行を追加しました。

mfl.Quit();

コンソール アプリケーションが実行されると、mfl32.exe が開始され、コンソール アプリケーションが閉じられると、mfl32.exe プロセスが終了します。

問題が発生するのは、私のコードでは、このアプリケーションへの呼び出しを別のスレッドで行う必要があることです。mfl32.exe プロセスはスレッドの最後で終了せず、コンソール アプリケーションが閉じたときにのみ削除されます。現在のコードは次のようになります。

namespace lt
{

class threadtest
{
    public void LaserTest()
    {

        Console.WriteLine("Worker thread started...");
        MFL32.Application mfl = new MFL32.Application();
        int i = 0;
        while (i < 50000)
        {
            i++;
        }
        mfl.Quit();
        Console.WriteLine("Worker thread now finished!");
    }

    void laser_AppQuit() // Quit event handler triggered
    {
        Console.WriteLine("The QUIT method has been caught. It should kill the lfm32.exe process");
    }
}



class Program
{
    static void Main(string[] args)
    {
        threadtest workerObject = new threadtest();
        Thread workerThread = new Thread(workerObject.LaserTest);
        workerThread.Start();
        Console.WriteLine("End of main thread reached");
        Console.ReadKey();
    }
}

}

別のスレッドの最後に到達したときではなく、メイン コンソール アプリケーションが終了したときにのみ、トリガーされた exe が終了する理由について何か考えはありますか?

4

2 に答える 2

1

を呼び出した後でも、未解決の COM 参照がある限り、サードパーティ プログラムはおそらく存続しますmfl.Quit()。「Quit()」メソッドの通常のセマンティックは、プロセスを強制的に (正常に) 終了させ、COM 参照を無効にすることであるため、これは少し奇妙です。

設計上、.Net は、参照を保持する変数 (アプリケーションへの COM 参照を保持するRCW またはランタイム呼び出し可能ラッパーオブジェクトへの参照を保持する変数) が出力されたときに、COM オブジェクトで Release() を呼び出しません。 .Net はガベージ コレクションされるため、スコープの。

Release()プロセス (技術的には AppDomain) が終了したとき、またはガベージ コレクターが RCW オブジェクトを収集することを決定したときにのみ、COM オブジェクトで呼び出されます。

RCW オブジェクトができると思ってDispose()いましたが、そうではありません。技術的な理由があるのか​​もしれません。.Net 1.0 の開発プロセスで RCW の動作を変更するには遅すぎるまで、dispose パターンが導入されなかったのかもしれません。

いずれにせよ、RCWRelease()にその COM 参照を強制的に呼び出すには、次のように呼び出します。

  Marshal.ReleaseComObject(mfl);

メソッドを呼び出した後にそれを試してQuit()、サードパーティ プログラムの動作が変わるかどうかを確認してください。

于 2013-05-31T13:13:49.593 に答える