簡體   English   中英

如何有效地殺死 C++ (Win32) 中的進程?

[英]How to effectively kill a process in C++ (Win32)?

我目前正在編寫一個非常輕量級的程序,所以我必須使用 C++,因為它沒有綁定到 .NET 框架,這大大增加了程序的大小。

我需要能夠終止進程,為此我需要獲得一個進程句柄。 不幸的是,我還沒有想出如何做到這一點。

PS我知道要殺死一個進程,你必須使用TerminateProcess

以下代碼有效:

const auto explorer = OpenProcess(PROCESS_TERMINATE, false, process_id);
TerminateProcess(explorer, 1);
CloseHandle(explorer);

OpenProcess() 所需的 PID 通常不容易獲得。 如果你得到的只是一個進程名稱,那么你需要迭代機器上正在運行的進程。 使用 CreateToolhelp32Snapshot 執行此操作,然后使用 Process32First 並使用 Process32Next 循環。 PROCESSENTRY32.szExeFile 為您提供進程名稱(不是路徑!),th32ProcessID 為您提供 PID。

下一個考慮是該過程可能出現不止一次。 並且有可能將相同的進程名稱用於非常不同的程序。 比如“設置”。 如果您不想將它們全部殺死,則需要嘗試從它們那里獲取一些運行時信息。 可能是窗口標題欄文本。 GetProcessImageFileName() 可以為您提供 .exe 的路徑。 它使用本機內核格式,您需要 QueryDosDevice 將磁盤驅動器設備名稱映射到驅動器號。

下一個考慮因素是您在 OpenProcess() 中要求的權限。 您不太可能獲得PROCESS_ALL_ACCESS ,您所需要的只是PROCESS_TERMINATE 雖然這也是特權。 確保您用於運行程序的帳戶可以獲得該權限。

與其經歷所有痛苦來殺死一個已知名稱的進程,為什么不簡單地調用“系統”並要求命令行殺死它呢?

例如,

int retval = ::_tsystem( _T("taskkill /F /T /IM MyProcess.exe") );

要獲取傳遞給TerminateProcess的句柄,請將OpenProcess與其他一些函數(如EnumProcesses )結合使用。

這是 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();
                }
            }
        }
    }
}

僅限窗戶

system("taskkill /f /im servicetokill.exe")

以下是一些用於終止名為“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);
                }
            }
        }
    }
}

CreateProcessOpenProcess返回進程句柄。

這是一些示例代碼,通過要求系統列出所有進程然后在列表中搜索您想要的進程來查找進程。

使用現代 C++ 的任務殺手

下面是我為終結者計划創建的代碼

//_____________________________________________
//                                             |
// TheNexGen of Terminator (inclusion version) |
// ------------------------------------------- |
//                                             |
// Add your Programs in the 'if' check as I've |
// listed below, and compile using c++17 flag  |
// or higher                                   |
//_____________________________________________|



#include <process.h>
#include <windows.h>
#include <tlhelp32.h>
#include <string_view>
using namespace std;

int main()
{
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) return 0;

    PROCESSENTRY32W pe32{ .dwSize = sizeof(PROCESSENTRY32) };
    if (!Process32First(hProcessSnap, &pe32)) return CloseHandle(hProcessSnap), 0;

    do
    {
        wstring_view str = pe32.szExeFile;

        if
            (
                str == L"chrome.exe"
                || str == L"AAM Update Notifier.exe"
                || str == L"About.exe"
                || str == L"ActionCenterDownloader.exe"
                || str == L"adb.exe"
                || str == L"AdobeARM.exe"
            )
        {
            if (HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, pe32.th32ProcessID))
            {
                TerminateProcess(hProcess, 1);
                CloseHandle(hProcess);
            }
        }
    }
    while (Process32Next(hProcessSnap, &pe32));

    CloseHandle(hProcessSnap);
}

描述

@DmitryBoyko提供的代碼的執行速度提高了 100 倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM