С++ контролирует запущенные процессы в фоновом режиме?

Я пытался написать программу на С++, которая будет отслеживать запущенные процессы в фоновом режиме и завершать определенный из них, если будет обнаружено, что он запущен. Я написал программу, которая будет это делать, однако единственный способ, который я могу придумать, - это использовать бесконечный цикл WHILE, который постоянно проверяет программу. Это, как вы можете себе представить, постоянно использует мощность и ресурсы ЦП для постоянного зацикливания. В диспетчере задач вы можете увидеть, что большинство запущенных процессов всегда используют 0% ЦП. Мой вопрос: как я могу написать или изменить эту программу для работы в фоновом режиме, используя 0% ЦП, пока она не обнаружит процесс, который должен завершиться? Вся моя программа ниже. В этом примере я использовал «Notepad.exe» в WinMain как процесс, который программа должна завершить.

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

person Eric Townsend    schedule 16.12.2011    source источник
comment
Быстрое исправление — Sleep(1) в цикле while(1). Не стесняйтесь увеличивать его, но 1 уже достаточно, чтобы уменьшить его почти до нуля.   -  person Hans Passant    schedule 17.12.2011
comment
Ага, спасибо, Ханс Пассант, за предложение. Это полностью решило мою проблему! И вам тоже спасибо, parapura rajkumar, за ваше предложение!   -  person Eric Townsend    schedule 17.12.2011


Ответы (1)


Вы можете использовать WMI и уведомления о событиях, чтобы узнать, когда процессы создаются и уничтожаются. . __InstanceCreationEvent это то, что вам нужно искать.

Создание ресурса: __InstanceCreationEvent

Предположим, вы заинтересованы в получении уведомления, если Блокнот запущен на определенном компьютере. При запуске Блокнота создается соответствующий процесс. Процессами можно управлять с помощью WMI, и они представлены классом Win32_Process. Когда Блокнот запускается, соответствующий экземпляр класса Win32_Process становится доступным через WMI. Если вы зарегистрировали свой интерес к этому событию (с помощью соответствующего запроса уведомления о событии), доступность этого экземпляра приводит к созданию экземпляра класса __InstanceCreationEvent.

person parapura rajkumar    schedule 16.12.2011
comment
Это не инстанцируемый класс WMI, подумайте об абстрактном базовом классе. Вы ищете Win32_ProcessStartTrace. stackoverflow.com/questions/3934898/detecting-child-processes/< /а> - person Hans Passant; 17.12.2011