[英]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);
}
}
}
}
}
CreateProcess
和OpenProcess
返回進程句柄。
這是一些示例代碼,通過要求系統列出所有進程然后在列表中搜索您想要的進程來查找進程。
下面是我為終結者計划創建的代碼
//_____________________________________________
// |
// 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.