2

CTRL_CLOSE_EVENT の処理方法を学習するために簡単なテスト プログラム (TestProgram.exe) を作成しました。ここに私の観察と質問があります。

1) TestProgram.exe をダブルクリックして起動し、タスク マネージャーに移動すると、TestProgram.exe が [アプリ] の下に表示されます。TestProgram.exe で「タスクの終了」を実行すると、CTRL_CLOSE_EVENT のハンドラが呼び出されます。

しかし

2) コマンド プロンプトを開いて TestProgram.exe を起動すると、タスク マネージャーの [バックグラウンド プロセス] に一覧表示され、同じプロセスで [タスクの終了] を実行しても CTRL_CLOSE_EVENT が発生しません。

私の実際のアプリケーションは、上記のケース 2) で説明したように使用されます。ユーザーが自分のアプリで終了タスクを実行したときにクリーンアップを実行したいと考えています (これは、タスク マネージャーの [バックグラウンド プロセス] の下に表示されます)。

ありがとう、クリシュナ

4

2 に答える 2

2

TerminateProcessプロセスが終了した (閉じられていない) 場合、フックまたはNtTerminateProcessタスク マネージャー プロセスで何らかのフックを開始しない限り、実際には何も実行できません。

#include <windows.h>
#include <assert.h>

BOOL WINAPI MyTerminateProcess(HANDLE hProcess, UINT uExitCode ) {
    MessageBox(NULL, TEXT("Do some cleanup"), NULL, MB_OK);
    ExitProcess(0);
    return TRUE;
}

#pragma pack(1)
typedef struct __PATCHDATA {
    BYTE push;
    DWORD address;
    BYTE ret;
} PATCHDATA;
#pragma pack()

int main(int argc, char **argv) {
    HMODULE hModule;
    DWORD written;
    // This struct contains assembly instruction that do:
    //  push address ; 0x68 MyTerminateProcess
    //  ret          ; 0xc3
    // so the execution will return to our hook
    PATCHDATA patch = {0x68, (DWORD) MyTerminateProcess, 0xc3};

    // remove this code, the program will terminate itself.
    // TODO: check the memory protection and modify it.
    WriteProcessMemory(GetCurrentProcess(),
                       TerminateProcess,
                       &patch,
                       sizeof(PATCHDATA),
                       &written);

    TerminateProcess(NULL, 0);

    return 0;
}

TerminateProcessこれは同じプロセスにフックされます。DLL で出荷し、タスク マネージャー プロセスに挿入する必要がありますが、テストしていません。しかし、この方法はやり過ぎで安全ではありません。AV 製品によっては、有害なプログラムとして検出される場合があります。

簡単な解決策は、@Martin James が提案したように、プログラムの起動時にクリーンアップすることです。プログラムの起動時にファイルを作成するか、レジストリを使用して のような値を保存します。プログラムが閉じられた場合、GUI の場合0は受け取った場合、またはコマンド プロンプトを閉じた場合は、クリーンアップを実行して を保存します。WM_CLOSECTRL_CLOSE_EVENT1

次の起動時に、まだ値が変わらない場合はその値を確認します0。これは、プログラムが適切に閉じられなかったことを意味し、クリーンアップが1必要ない場合はクリーンアップを行い、保存して次に0進みます。

多くのプログラムは、このメソッドを使用して、プログラムが適切に閉じられたかどうかを検出します。

于 2013-08-27T03:40:30.500 に答える