2011-12-16 21 views
1

私は実行中のプロセスをバックグラウンドで監視し、実行中であれば特定のプロセスを終了するプログラムをC++で作成しようとしています。私はそうするプログラムを書いたが、私がこれを行うために考えることができる唯一の方法は、プログラムをチェックし続ける無限のWHILEループを使うことである。これは、あなたが想像しているように、常にCPUパワーとリソースを使用して常にループしています。タスクマネージャでは、実行中のほとんどのプロセスが常にCPUの0%を使用していることがわかります。私の質問は次のとおりです。このプログラムをバックグラウンドで実行するには、終了するはずのプロセスが検出されるまでCPUの0%を利用してこのプログラムを作成または変更するにはどうすればよいですか? 私のプログラム全体は以下の通りです。この例では、プログラムを終了するプロセスとして「Notepad.exe」をWinMainに使用しています。C++はプロセスをバックグラウンドで監視していますか?

#include <Windows.h> 
#include <iostream> 
#include <tlhelp32.h> 
#include <string> 
#define TA_FAILED 0 
#define TA_SUCCESS_CLEAN 1 
#define TA_SUCCESS_KILL 2 

DWORD WINAPI TerminateApp(DWORD dwPID, DWORD dwTimeout); 
DWORD WINAPI Terminate16App(DWORD dwPID, DWORD dwThread, WORD w16Task, DWORD dwTimeout); 

typedef struct { 
    DWORD dwID; 
    DWORD dwThread; 
} TERMINFO; 

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM lParam) ; 

DWORD WINAPI TerminateApp(DWORD dwPID, DWORD dwTimeout) { 
    HANDLE hProc ; 
    DWORD dwRet ; 

    // If we can't open the process with PROCESS_TERMINATE rights, 
    // then we give up immediately. 
    hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, 
    dwPID); 

    if(hProc == NULL) { 
    return TA_FAILED ; 
    } 

    // TerminateAppEnum() posts WM_CLOSE to all windows whose PID 
    // matches your process's. 
    EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ; 

    // Wait on the handle. If it signals, great. If it times out, 
    // then you kill it. 
    if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0) 
    dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED); 
    else 
    dwRet = TA_SUCCESS_CLEAN ; 

    CloseHandle(hProc) ; 

    return dwRet ; 
} 

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM lParam) { 
    DWORD dwID ; 

    GetWindowThreadProcessId(hwnd, &dwID) ; 

    if(dwID == (DWORD)lParam) { 
    PostMessage(hwnd, WM_CLOSE, 0, 0) ; 
    } 
    return TRUE ; 
} 

DWORD FindProcessId(const std::string& processName); 

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { 

    std::string process1 = "Notepad.exe"; 
    while (1) { 
    TerminateApp(FindProcessId(process1),0); 
    } 
return 0; 
} 

DWORD FindProcessId(const std::string& processName) { 

    PROCESSENTRY32 processInfo; 
    processInfo.dwSize = sizeof(processInfo); 

    HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); 
    if (processesSnapshot == INVALID_HANDLE_VALUE) { 
     return 0; 
    } 
    Process32First(processesSnapshot, &processInfo); 
    if (!processName.compare(processInfo.szExeFile)) { 
     CloseHandle(processesSnapshot); 
     return processInfo.th32ProcessID; 
    } 

    while (Process32Next(processesSnapshot, &processInfo)) { 

     if (!processName.compare(processInfo.szExeFile)) { 
     CloseHandle(processesSnapshot); 
     return processInfo.th32ProcessID; 
     } 
    } 
    CloseHandle(processesSnapshot); 
    return 0; 
} 
+0

while(1)ループでクイックフィックスは 'Sleep(1)'です。それを大きくすることを躊躇しないでくださいが、1は既にゼロに近づけるのに十分です。 –

+0

Aha、提案のためのHans Passantに感謝します。それは私の問題を完全に解決しました!また、あなたの提案にもparapura rajkumarもありがとう! –

答えて

0

WMI and event通知を使用して、プロセスの作成と破棄を検出できます。 __InstanceCreationEventが必要です。リソースの

作成:__InstanceCreationEvent

メモ帳が特定のコンピュータ上で実行される場合は、通知を受け取ることに興味を持っていると仮定します。メモ帳が実行されると、対応するプロセスが作成されます。プロセスはWMIを使用して管理することができ、Win32_Processクラスで表されます。メモ帳が実行されると、Win32_Processクラスの対応するインスタンスがWMIを通じて使用可能になります。このイベントへの興味を(適切なイベント通知クエリを発行することによって)登録した場合、このインスタンスの可用性により、__InstanceCreationEventクラスのインスタンスが作成されます。

+0

これはインスタンス化可能なWMIクラスではありません。「抽象基本クラス」と考えてください。あなたはWin32_ProcessStartTraceを探しています。 http://stackoverflow.com/questions/3934898/detecting-child-processes/3935400#3935400 –

関連する問題