Как эффективно убить процесс в C ++ (Win32)? - PullRequest
14 голосов
/ 16 декабря 2009

В настоящее время я пишу очень легковесную программу, поэтому мне приходится использовать C ++, поскольку он не привязан к .NET framework, что значительно увеличивает размер программы.

Мне нужно иметь возможность завершить процесс, и для этого мне нужно получить дескриптор процесса. К сожалению, я пока не понял, как это сделать.

P.S. Я знаю, что для уничтожения процесса вы должны использовать TerminateProcess .

Ответы [ 8 ]

16 голосов
/ 16 декабря 2009

PID, необходимый для OpenProcess (), обычно не так просто заполучить. Если все, что у вас есть, это имя процесса, то вам нужно выполнить итерации запущенных процессов на компьютере. Сделайте это с CreateToolhelp32Snapshot, затем Process32First и выполните цикл с Process32Next. PROCESSENTRY32.szExeFile дает вам имя процесса (не путь!), Th32ProcessID дает вам PID.

Следующее соображение заключается в том, что процесс может появляться более одного раза. И есть вероятность, что одно и то же имя процесса используется для самых разных программ. Вроде «Настройка». Если вы не хотите просто убить их всех, вам нужно попытаться получить от них некоторую информацию во время выполнения. Текст строки заголовка окна, возможно. GetProcessImageFileName () может дать вам путь к .exe. Он использует собственный формат ядра, вам понадобится QueryDosDevice, чтобы сопоставить имя устройства дисковода с буквой диска.

Следующее рассмотрение - это права, которые вы запрашиваете в OpenProcess (). Вы вряд ли получите PROCESS_ALL_ACCESS, все, что вам нужно, это PROCESS_TERMINATE. Хотя это и привилегия. Убедитесь, что учетная запись, которую вы используете для запуска своей программы, может получить это право.

14 голосов
/ 02 марта 2012

Вместо того, чтобы пройти через всю эту боль, чтобы убить процесс с известным именем, почему бы просто не вызвать «system» и попросить командную строку убить его?

Например,

int retval = ::_tsystem( _T("taskkill /F /T /IM MyProcess.exe") );
7 голосов
/ 16 декабря 2009
HANDLE explorer;
explorer = OpenProcess(PROCESS_ALL_ACCESS,false,2120);
TerminateProcess(explorer,1);

Это сработало

5 голосов
/ 16 декабря 2009

Чтобы получить дескриптор для передачи TerminateProcess , используйте OpenProcess в сочетании с некоторыми другими функциями, такими как EnumProcesses .

3 голосов
/ 24 сентября 2015

Вот полный пример проекта Visual Studio 2010 C ++, как убить процесс с помощью EXE имени файла.

Чтобы проверить это, просто запустите Internet Explorer и после этого выполните следующий код.

#include <iostream>
#include <string>
#include<tchar.h>
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>

using namespace std;

//  Forward declarations:
BOOL GetProcessList();
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode);

int main( void )
{
  GetProcessList( );
  return 0;
}

BOOL GetProcessList( )
{
  HANDLE hProcessSnap;
  HANDLE hProcess;
  PROCESSENTRY32 pe32;
  DWORD dwPriorityClass;

  // Take a snapshot of all processes in the system.
  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
  if( hProcessSnap == INVALID_HANDLE_VALUE )
  {   
    return( FALSE );
  }

  // Set the size of the structure before using it.
  pe32.dwSize = sizeof( PROCESSENTRY32 );

  // Retrieve information about the first process,
  // and exit if unsuccessful
  if( !Process32First( hProcessSnap, &pe32 ) )
  {   
    CloseHandle( hProcessSnap );  // clean the snapshot object
    return( FALSE );
  }

  // Now walk the snapshot of processes 
  do
  {  
    string str(pe32.szExeFile);

    if(str == "iexplore.exe") // put the name of your process you want to kill
    {
        TerminateMyProcess(pe32.th32ProcessID, 1);
    } 
  } while( Process32Next( hProcessSnap, &pe32 ) );

  CloseHandle( hProcessSnap );
  return( TRUE );
}

BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode)
{
    DWORD dwDesiredAccess = PROCESS_TERMINATE;
    BOOL  bInheritHandle  = FALSE;
    HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
    if (hProcess == NULL)
        return FALSE;

    BOOL result = TerminateProcess(hProcess, uExitCode);

    CloseHandle(hProcess);

    return result;
}

Представьте, что в C # это выглядит как

using System;
using System.Collections.Generic;
using System.Text;

namespace MyProcessKiller
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (System.Diagnostics.Process myProc in System.Diagnostics.Process.GetProcesses())
            {
                if (myProc.ProcessName == "iexplore")
                {
                    myProc.Kill();
                }
            }
        }
    }
}
1 голос
/ 16 декабря 2009

CreateProcess и OpenProcess обработчики возврата.

Вот пример примера кода , чтобы найти процесс, попросив систему перечислить все процессы и затем выполнить поиск в списке нужного процесса.

0 голосов
/ 03 марта 2018

только для окон

system("taskkill /f /im servicetokill.exe")
0 голосов
/ 17 июля 2014

Вот несколько примеров рабочих кодов для уничтожения процесса, который называется «ShouldBeDead.exe»:

// you will need these headers, and you also need to link to Psapi.lib
#include <tchar.h>
#include <psapi.h>

...
// first get all the process so that we can get the process id 
DWORD processes[1024], count;
if( !EnumProcesses( processes, sizeof(processes), &count ) )
{
    return false;
}

count /= sizeof(DWORD);
for(unsigned int i = 0; i < count; i++)
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    if(processes[i] != 0)
    {
        // remember to open with PROCESS_ALL_ACCESS, otherwise you will not be able to kill it
        HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, processes[i] );
        if(NULL != hProcess)
        {
            HMODULE hMod;
            DWORD cbNeeded;
            if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
            {
                GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR));

                // find the process and kill it
                if(strcmp(szProcessName, "ShouldBeDead.exe") == 0)
                {
                    DWORD result = WAIT_OBJECT_0;
                    while(result == WAIT_OBJECT_0)
                    {
                        // use WaitForSingleObject to make sure it's dead
                        result = WaitForSingleObject(hProcess, 100);
                        TerminateProcess(hProcess, 0);
                    }

                    CloseHandle(hProcess);
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...