【问题标题】:C++ monitor running processes in the background?C ++在后台监视正在运行的进程?
【发布时间】:2012-01-22 08:12:13
【问题描述】:

我一直在尝试用 C++ 编写一个程序,该程序将在后台监视正在运行的进程,并在检测到某个进程正在运行时终止某个进程。我已经编写了一个可以这样做的程序,但是我能想到的唯一方法是使用无限的WHILE 循环来不断检查程序。正如您可以想象的那样,这会不断地使用 CPU 功率和资源来不断循环。在任务管理器中,您可以看到大多数正在运行的进程始终使用 0% 的 CPU。我的问题是:我如何编写或修改这个程序以在后台运行,利用 0% 的 CPU 直到它检测到它应该终止的进程? 我的整个程序如下。在这个例子中,我在WinMain 中使用了“Notepad.exe”作为程序应该终止的进程。

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

【问题讨论】:

  • 在 while(1) 循环中的快速修复是Sleep(1)。不要犹豫,让它变大,但 1 已经足以让它接近零。
  • 啊哈,谢谢 Hans Passant 的建议。这完全解决了我的问题!也感谢 parapura rajkumar 的建议!

标签: windows background process monitor terminate


【解决方案1】:

您可以使用WMI and event 通知来查找进程的创建和销毁时间。 __InstanceCreationEvent 是您需要寻找的。​​p>

创建资源:__InstanceCreationEvent

假设您有兴趣在某台计算机上运行记事本时接收通知。记事本运行时,会创建相应的进程。进程可以使用 WMI 进行管理,并由 Win32_Process 类表示。当记事本开始运行时,Win32_Process 类的相应实例将通过 WMI 变得可用。如果您已注册对此事件感兴趣(通过发出适当的事件通知查询),则此实例的可用性将导致创建 __InstanceCreationEvent 类的实例。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2013-09-25
  • 2021-04-06
  • 2013-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多