14

構成ファイルでユーザーが指定した他の任意のプロセスを呼び出せるようにしたいアプリケーションAがあります。

バッチスクリプトBは、ユーザーがAによって呼び出されることを望むそのようなプロセスの1つです。Bは、いくつかの環境変数を設定し、いくつかのメッセージを表示し、コンパイラCを呼び出していくつかの作業を行います。

Windowsは、任意のプロセスを正常に終了するための標準的な方法を提供しますか?Aがコンソールで実行され、CTRL+Cを受け取ったとします。これをBとCに渡すことはできますか?Aがウィンドウ内で実行され、ユーザーがウィンドウを閉じようとした場合、BとCをキャンセルできますか?

TerminateProcessはオプションですが、あまり良いものではありません。AがBでTerminateProcessを使用する場合、Cは実行を継続します。これは、Cが長時間実行されている場合に厄介な問題を引き起こす可能性があります。これは、Cの最初のインスタンスがまだ密かに機能している間に、同じファイルを操作するためにCの別のインスタンスを開始する可能性があるためです。さらに、TerminateProcessはクリーンな終了にはなりません。

GenerateConsoleCtrlEventは良さそうに聞こえ、すべてがコンソールで実行されているときに機能する可能性がありますが、ドキュメントにはCTRL + Cを自分のコンソールにのみ送信できると記載されているため、Aがウィンドウで実行されている場合は役に立ちません。

WindowsでSIGINTに相当するものはありますか?このような記事を見つけたいと思います:http://www.cons.org/cracauer/sigint.htmlforWindows

4

2 に答える 2

9

私はこの質問に少し遅れていると思いますが、同じ問題を抱えている人のためにとにかく何かを書きます。

私の問題は、アプリケーションをGUIアプリケーションにしたいという点で似ていますが、実行されるプロセスは、インタラクティブなコンソールウィンドウを接続せずにバックグラウンドで実行する必要があります。

GenerateConsoleCtrlEvent()を使用してこれを解決することができました。トリッキーな部分は、ドキュメントがそれをどのように使用できるか、そしてそれの落とし穴について正確に明確ではないということです。

私の解決策は、ここで説明されていることに基づいています。しかし、それは実際にはすべての詳細を説明していなかったので、ここにそれを機能させる方法の詳細があります。

  1. 新しいヘルパーアプリケーション「Helper.exe」を作成します。このアプリケーションは、アプリケーション(親)と閉じたい子プロセスの間に配置されます。また、実際の子プロセスも作成します。この「仲介者」プロセスが必要です。そうしないと、GenerateConsoleCtrlEvent()が失敗します。

  2. ある種のIPCメカニズムを使用して、親からヘルパープロセスに、ヘルパーが子プロセスを閉じる必要があることを伝えます。ヘルパーがこのイベントを取得すると、「GenerateConsoleCtrlEvent(CTRL_BREAK、0)」を呼び出し、それ自体と子プロセスを閉じます。子プロセスをキャンセルしたいときに親が完了するイベントオブジェクトを自分で使用しました。

Helper.exeを作成するには、CREATE_NO_WINDOWおよびCREATE_NEW_PROCESS_GROUPを使用して作成します。また、子プロセスを作成するときは、フラグ(0)なしで作成します。これは、親からコンソールを派生させることを意味します。これを行わないと、イベントが無視されます。

各ステップがこのように行われることが非常に重要です。私はさまざまな種類の組み合わせを試してきましたが、この組み合わせだけが機能します。CTRL_Cイベントを送信することはできません。成功を返しますが、プロセスによって無視されます。CTRL_BREAKが機能する唯一のものです。どちらも最終的にExitProcess()を呼び出すため、実際には問題ではありません。

また、子プロセスIDのプロセスグループ化IDを使用してGenerateConsoleCtrlEvent()を呼び出して、ヘルパープロセスが存続できるようにすることもできません。これも失敗します。

私はこれを機能させるために一日を過ごしました。この解決策は私にとってはうまくいきますが、他に何か追加するものがあれば、やってください。私は他のすべてのネットに行き、同様の問題を抱えている多くの人々を見つけましたが、問題に対する明確な解決策はありませんでした。GenerateConsoleCtrlEvent()の動作も少し奇妙なので、誰かがそれについての詳細を知っているなら、共有してください。

于 2010-03-12T08:13:26.700 に答える
8

@ShaktaGenerateConsoleCtrlEvent()が言ったように、非常にトリッキーですが、ヘルパープロセスなしでCtrl+Cを送信できます。

void SendControlC(int pid)
{
    AttachConsole(pid); // attach to process console
    SetConsoleCtrlHandler(NULL, TRUE); // disable Control+C handling for our app
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); // generate Control+C event
}
于 2012-10-15T15:49:15.843 に答える