【问题标题】:Need Win32 API C++ code that is equivalent to "taskkill /T /F /PID XXX"需要相当于“taskkill /T /F /PID XXX”的Win32 API C++代码
【发布时间】:2022-01-07 17:32:52
【问题描述】:

以下代码可以“杀死 -9”我的进程(见下文)。但我宁愿不要仅仅为了从我的 C++ 程序中杀死一个进程而使用 cmd.exe。是否有一种纯粹的 Win32 API 方式来执行此操作,特别是具有“/T 和 /F”标志的效果。我不得不相信这是可能的,因为 taskkill.exe 是用 Win32 API 编写的。

    #include <iostream>
    #include <string>

    void KillDash9(unsigned long PID) {
        std::string killcmd = std::string("") 
                            + std::string("taskkill /T /F /PID ") 
                            + std::to_string(PID);
        std::cout << killcmd << std::endl;
        system(killcmd.c_str());
    }

以下是我尝试过但不起作用的方法:

void KillDash9_v2(unsigned long PID) {
    HANDLE pHandle = OpenProcess(
    /*[in] DWORD dwDesiredAccess*/ PROCESS_TERMINATE | SYNCHRONIZE,
    /*[in] BOOL  bInheritHandle*/  TRUE,
    /*[in] DWORD dwProcessId*/     PID
    );
    TerminateProcess(pHandle, 0);
    WaitForSingleObject(pHandle, 500);
    CloseHandle(pHandle);
}
 

KillDash9_v2() 不会终止进程:

"powershell -command ping -t localhost"  

但是,KillDash9_v1() 可以杀死这个进程。

如何让 KillDash9_v2() 以同样的方式工作? v2会杀死powershell(3328),但不会杀死在杀死7236后继续运行的ping.exe(7236)。我需要以某种方式枚举从7246开始的进程树并杀死它下面的每个分支。

我按照建议添加了错误检查。

void KillDash9_v3(unsigned long PID) {

    // Clear Windows Error Variable
    SetLastError(0);

    HANDLE pHandle = OpenProcess(
    /*[in] DWORD dwDesiredAccess*/ PROCESS_TERMINATE | SYNCHRONIZE,
    /*[in] BOOL  bInheritHandle*/  FALSE,
    /*[in] DWORD dwProcessId*/     PID
    );
    if (pHandle == nullptr) {
        long int err = GetLastError();
        std::string msg = std::string("ERROR  : OpenProcess failed for PID(") + std::to_string(PID) + std::string(")\n")
                        + std::string("REASON : ") + WindowsGetErrorString(err) + std::string("\n")
                        + std::string("CODE   : ") + std::to_string(err) + std::string("\n");
        std::cout << msg;
        return;
    }

    // Clear Windows Error Variable
    SetLastError(0);

    BOOL rc = TerminateProcess(pHandle, 0);
    if (rc == 0) {
        long int err = GetLastError();
        std::string msg = std::string("ERROR:  TerminateProcess failed for PID(") + std::to_string(PID) + std::string(")\n")
                   + std::string("REASON: ") + WindowsGetErrorString(err) + std::string("\n")
                   + std::string("CODE   : ") + std::to_string(err) + std::string("\n");
        std::cout << msg;
        return;
    }

    WaitForSingleObject(pHandle, 500);
    CloseHandle(pHandle);
}

【问题讨论】:

  • 你应该检查OpenProcess返回的句柄是否有效。浏览它的文档
  • 它必须是有价值的,因为它适用于 taskkill.exe...为什么 TerminateProcess 不是相同的 PID?
  • 由于进程访问权限,OpenProcess 可能会失败。这就是为什么你应该检查它返回的句柄是否有效。
  • 好建议...我试试看。
  • @pico 不过,有一种更简单的方法可以杀死生成的进程树。使用CreateProcess...() 生成新进程时,将新进程放入作业对象中。它创建的任何子进程也将被放入同一个作业中(默认情况下,可以被覆盖)。然后你可以简单地terminate the job object

标签: c++ winapi


【解决方案1】:
void ProcessKillTree_v1(unsigned long PARENT_PID)
{
    std::string killcmd = std::string("") 
          + std::string("taskkill /T /F /PID ") 
          + std::to_string(PARENT_PID);
    std::cout << killcmd << std::endl;
    system(killcmd.c_str());
}
void ProcessKillTree_v2(unsigned long PARENT_PID)
{
    if(PARENT_PID > 0) {

        // Kill Tree
        HANDLE snapshot = CreateToolhelp32Snapshot(
            TH32CS_SNAPPROCESS, 0);

        if(snapshot) {
            PROCESSENTRY32 process;
            ZeroMemory(&process, sizeof(process));
            process.dwSize = sizeof(process);

            if(Process32First(snapshot, &process)) {
                do {
                    if(process.th32ParentProcessID==PARENT_PID) {
                        HANDLE process_handle 
                             = OpenProcess(
                                  PROCESS_TERMINATE, 
                                  FALSE, 
                                  process.th32ProcessID
                             );

                        if(process_handle) {
                            ProcessKillTree(process.th32ProcessID);
                            //TerminateProcess(process_handle, 2);
                            //CloseHandle(process_handle);
                        }
                    }
                }
                while (Process32Next(snapshot, &process));
            }
            CloseHandle(snapshot);
        }

        // Kill Parent
        HANDLE parent_handle = OpenProcess(
                                  PROCESS_TERMINATE, 
                                  FALSE, 
                                  PARENT_PID);
        TerminateProcess(parent_handle, 2);
        CloseHandle(parent_handle);
    }
}

【讨论】:

    猜你喜欢
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多