C++ monitor running processes in the background?

2019-08-02 09:37发布

问题:

I've been trying to write a program in C++ that will monitor running processes in the background and terminate a certain one if it's detected to be running. I have written a program that will do so, however the only way I can think of to do this is to use an infinite WHILE loop that keeps checking for the program. This, as you can imagine, constantly uses CPU power and resources to be constantly looping. In task manager, you can see that most processes that are running are always using 0% of the CPU. My question is: How can I write or modify this program to run in the background, utilizing 0% of the CPU until it detects the process it's supposed to terminate? My entire program is below. In this example, I have used "Notepad.exe" in WinMain as the process the program should be terminating.

#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;
}

回答1:

You can use WMI and event notification to find when processes are created and destroyed. __InstanceCreationEvent is what you need to look for.

Creation of a resource: __InstanceCreationEvent

Suppose you are interested in receiving a notification if Notepad is run on a certain computer. When Notepad runs, a corresponding process is created. Processes can be managed by using WMI and are represented by the Win32_Process class. When Notepad starts running, a corresponding instance of the Win32_Process class becomes available through WMI. If you have registered your interest in this event (by issuing the appropriate event notification query), the availability of this instance results in the creation of an instance of the __InstanceCreationEvent class.