Windows编程—杀死指定路径程序文件的进程

前言

由于Windows命令 taskkill 无法通过程序文件的完整路径匹配来杀死指定进程,通过程序名称容易误杀进程,所有笔者做了一个简单的封装做了个mytaskkill.exe,用来杀死指定路径的程序文件的进程。

支持Windows xp 及以上版本,用法为:mytaskkill.exe “C:\xxx1.exe” “C:\xxx2.exe” “C:\xxx3.exe”

源码

使用wmi命令和taskkill命令结合来杀死指定路径程序文件的进程,使用了Windows管道读取命令输出信息进而找到指定路径名进程的PID 然后使用taskkill 干掉这个PID。编码中使用了 boost库用来操作字符串,所以源码编译要自己指定boost头文件和库文件路径。

核心代码如下:

/*
    杀死指定路径程序的所有进程
*/
BOOL KillSpecifiedProcess(const std::string& p_strPath)
{
    /*
    C:\Users\10139>wmic process where name="notepad.exe" get executablepath,processid
    ExecutablePath                   ProcessId
    C:\WINDOWS\system32\notepad.exe  6196
    C:\WINDOWS\system32\notepad.exe  6056


    C:\Users\10139>taskkill /F /PID 6196 /PID 6056
    成功: 已终止 PID 为 6196 的进程。
    成功: 已终止 PID 为 6056 的进程。
    */
    if(!boost::filesystem::exists(p_strPath))
    {
        cout << p_strPath << " not exist" << endl;
        return FALSE;
    }
    int index = p_strPath.rfind("\\");
    std::string strName = p_strPath.substr(index + 1);
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;
    HANDLE hStdOutRead = NULL, hStdOutWrite = NULL;
    if (!CreatePipe(&hStdOutRead, &hStdOutWrite, &sa, 0))
    {
        cout << "create pipe error," << GetLastError() << endl; 
        return FALSE;
    }
    STARTUPINFOA startInfo;
    PROCESS_INFORMATION procInfo;
    BOOL bSuccess = FALSE;
    ZeroMemory(&procInfo, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&startInfo, sizeof(STARTUPINFOA));
    startInfo.cb = sizeof(STARTUPINFOA);
    startInfo.hStdOutput = hStdOutWrite;
    startInfo.dwFlags |= (STARTF_USESTDHANDLES |STARTF_USESHOWWINDOW) ;
    startInfo.wShowWindow = SW_HIDE;
   
    boost::format fmt("wmic process where name=\"%1%\" get executablepath,processid");
    fmt % strName;
    std::string strSQL = fmt.str();
    bSuccess = CreateProcessA(NULL, (char*)strSQL.data(), NULL, NULL, TRUE, 0, NULL, NULL, &startInfo, &procInfo);
    if (!bSuccess)
    {
        cout << "create process error," << GetLastError() << endl;
        return FALSE;
    }
    WaitForSingleObject(procInfo.hProcess,INFINITE);
    CloseHandle(hStdOutWrite);
    DWORD byteRead = 0;
    std::string strContent;
    char buffer[READ_ONE_NUM] = {0};
    while (true)
    {
        byteRead = 0;
        memset(buffer, 0, READ_ONE_NUM);
        BOOL bRead = ReadFile(hStdOutRead, buffer, (READ_ONE_NUM-1)* sizeof(buffer[0]) , &byteRead, NULL);
        if (!bRead)
        {
            break;
        }
        strContent.append(buffer);
    }
    CloseHandle(hStdOutRead);
    std::vector<std::string> splitVec;
    boost::split(splitVec, strContent, boost::is_any_of("\r\n"), boost::token_compress_on);
    if(splitVec.size() > 0)
    {
        if( !boost::icontains(splitVec[0], "ExecutablePath") )
        {
            // 没有这个进程名
            cout << strName << " is not runing" << endl;
            return FALSE;
        }
        // 下面for代码:可以优化使用正则表达式来获取程序完整路径和程序PID
        // 第1行和最后1行都不是
        for(int i = 1; i < splitVec.size() -1; i++)
        {
            std::vector<std::string> splitVec2;
            boost::split(splitVec2, splitVec[i], boost::is_any_of(" "), boost::token_compress_on);
            int size = splitVec2.size();
            if(size >= 3)
            {
                std::string exePath;
                // 取到同名程序的完整路径
                for(int i = 0; i < size -1 -1; i++)
                {
                    exePath.append(splitVec2[i]);
                    exePath.append(" ");
                }
                // 判定路径是否完全匹配
                if( !boost::icontains(exePath, p_strPath) )
                {
                    continue;
                }

                // 程序路径可能有空格,倒数第2项为pid
                std::string pId =  splitVec2[size -1 -1];
                std::string cmd = "taskkill /F /PID ";
                cmd.append(pId);
                cout << p_strPath << "->" << cmd << endl;
                WinExec(cmd.c_str(), SW_HIDE);
            }
        }
    }
    return TRUE;
}

程序及代码下载

编译好的可执行程序和源代码下载点击这里

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值