纯代码方式杀死指定进程名的进程(Linux&Windows)
1、命令行方式
1.1、Linux
> pidof sftp-server | xargs kill -9
1.2、Windows
> taskkill /im softwareName.exe /f
1.3、合入代码中,linux可以使用system,windows可以使用system、winexec等方式执行
#ifdef __linux__
system("pidof softwareName | xargs kill -9");
#elif _WIN32
system("taskkill /im softwareName /f"); //会弹出黑框一闪而过
//不弹出黑框,但是若执行完WinExec立即shellexecute或createprocess执行刚刚kill的软件会出现软件被杀的情况。
// 详情请见:https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-winexec
WinExec("taskkill /im softwareName /f",SW_HIDE);
#endif
2、纯代码方式
Windows下的方案:
使用CreateToolhelp32Snapshot获取当前系统中所有进程的快照
使用Process32Next循环遍历每一个进程信息
比较进程名若相符,使用OpenProcess根据进程信息中的pid打开进程句柄
使用TerminateProcess终止进程
Linux下的方案:
手写pidof通过进程名获取pid列表
打开/proc文件夹
遍历/proc文件夹下的文件,若为数字继续执行
使用readlink读取pid文件夹下的exe获取进程名
判断进程名是否与指定的进程名一致,若一致则将该pid放入到vector中
使用kill API杀死pid
代码如下
#ifdef __linux__
#include
#include
#include
#include
#include
#include
#include
#include
int pidof(const std::string& procName,std::vector& pids)
{
DIR *dir = nullptr;
struct dirent *dEnt = nullptr;
int pid = 0, i = 0;
char *s = nullptr;
int pnlen = 0;
dir = opendir("/proc");
if(!dir)
{
return -1;
}
pnlen = procName.size();
while((dEnt = readdir(dir)) != nullptr)
{
char exe[PATH_MAX + 1] = {0};
char path[PATH_MAX + 1] = {0};
int len = 0;
if((pid = atoi(dEnt->d_name)) == 0)
continue;
snprintf(exe,sizeof(exe),"/proc/%s/exe",dEnt->d_name);
if((len = readlink(exe,path,PATH_MAX)) < 0)
{
continue;
}
path[len] = '\0';
s = strrchr(path,'/');
if(s == nullptr) continue;
s++;
if(!strncmp(procName.c_str(),s,pnlen))
{
if(s[pnlen] == ' ' || s[pnlen] == '\0'){
pids.push_back(pid);
}
}
}
closedir(dir);
return 0;
}
BOOL KillProcessFromName(const std::string& strProcessName)
{
std::vector pids;
pidof(strProcessName,pids);
for(auto &pid:pids)
{
kill(pid,SIGKILL);
}
}
#elif _WIN32
#include "tlhelp32.h"
BOOL KillProcessFromName(const std::wstring& strProcessName)
{
//创建进程快照(TH32CS_SNAPPROCESS表示创建所有进程的快照)
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
//PROCESSENTRY32进程快照的结构体
PROCESSENTRY32 pe;
//实例化后使用Process32First获取第一个快照的进程前必做的初始化操作
pe.dwSize = sizeof(PROCESSENTRY32);
//下面的IF效果同:
//if(hProcessSnap == INVALID_HANDLE_VALUE) 无效的句柄
if (!Process32First(hSnapShot, &pe))
{
return FALSE;
}
//如果句柄有效 则一直获取下一个句柄循环下去
while (Process32Next(hSnapShot, &pe))
{
//pe.szExeFile获取当前进程的可执行文件名称
wstring scTmp = pe.szExeFile;
if (scTmp == strProcessName)
{
//从快照进程中获取该进程的PID(即任务管理器中的PID)
DWORD dwProcessID = pe.th32ProcessID;
HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID);
::TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
return TRUE;
}
}
return FALSE;
}
#endif