如何在C++中通过其名称获取进程句柄?

Mal*_*ist 55 c++ winapi process

我正在尝试获取example.exe的进程句柄,所以我可以调用TerminateProcess它.我怎样才能做到这一点?请注意,它没有窗口,因此FindWindow无法工作.

xia*_*ian 76

#include <cstdio>
#include <windows.h>
#include <tlhelp32.h>

int main( int, char *[] )
{
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if (Process32First(snapshot, &entry) == TRUE)
    {
        while (Process32Next(snapshot, &entry) == TRUE)
        {
            if (stricmp(entry.szExeFile, "target.exe") == 0)
            {  
                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);

                // Do stuff..

                CloseHandle(hProcess);
            }
        }
    }

    CloseHandle(snapshot);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此外,如果您想在OpenProcess中使用PROCESS_ALL_ACCESS,您可以尝试这样做:

#include <cstdio>
#include <windows.h>
#include <tlhelp32.h>

void EnableDebugPriv()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL);

    CloseHandle(hToken); 
}

int main( int, char *[] )
{
    EnableDebugPriv();

    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if (Process32First(snapshot, &entry) == TRUE)
    {
        while (Process32Next(snapshot, &entry) == TRUE)
        {
            if (stricmp(entry.szExeFile, "target.exe") == 0)
            {  
                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);

                // Do stuff..

                CloseHandle(hProcess);
            }
        }
    }

    CloseHandle(snapshot);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 您的代码将跳过系统中的第一个进程(但是,第一个进程很可能是"SYSTEM",因此没有用户可见的错误.) (6认同)
  • (char*)entry.szExeFile (6认同)
  • 将其更改为:HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ + PROCESS_TERMINATE,FALSE,entry.th32ProcessID); 我会给你答案 (2认同)
  • 我已经从这个答案中取得了很大进展 - 非常感谢所有贡献者.我遇到了许可问题.即使使用EnableDebugPriv,当我尝试打开不属于我自己的进程时,"我得到OpenProcess失败,错误5(访问被拒绝)".就我而言,我正在寻找所有用户的iexplore. (2认同)
  • 很好的答案!您应该使用`if(_tcsicmp(entry.szExeFile,_T("ta​​rget.exe"))== 0)`更改行`if(stricmp(entry.szExeFile,"target.exe")== 0)`在Unicode和ANSI编译标志之间进行更改时保持类型完整性. (2认同)
  • 请注意像我这样喜欢按字母顺序排列标题的人 - 必须在 `tlhelp32.h` 之前包含 `windows.h` 否则你最终会遇到有关未定义函数的令人困惑的错误(因为定义依赖于 `windows.h` `) (2认同)

Mic*_*ael 15

以下代码显示了如何使用toolhelp和OpenProcess来获取进程的句柄.为简洁起见,删除了错误处理.

HANDLE GetProcessByName(PCSTR name)
{
    DWORD pid = 0;

    // Create toolhelp snapshot.
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 process;
    ZeroMemory(&process, sizeof(process));
    process.dwSize = sizeof(process);

    // Walkthrough all processes.
    if (Process32First(snapshot, &process))
    {
        do
        {
            // Compare process.szExeFile based on format of name, i.e., trim file path
            // trim .exe if necessary, etc.
            if (string(process.szExeFile) == string(name))
            {
               pid = process.th32ProcessID;
               break;
            }
        } while (Process32Next(snapshot, &process));
    }

    CloseHandle(snapshot);

    if (pid != 0)
    {
         return OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    }

    // Not found


       return NULL;
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*edy 12

有两种基本技术.第一个使用PSAPI; MSDN有一个例子,使用EnumProcesses,OpenProcess,EnumProcessModules,和GetModuleBaseName.

另一个使用Toolhelp,我更喜欢.使用CreateToolhelp32Snapshot来获取进程列表的快照,走在它与Process32FirstProcess32Next,它提供了模块名称和进程ID,直到你找到你想要的,然后调用OpenProcess得到的句柄.


Bul*_*aza 5

可以使用以下代码:

DWORD FindProcessId(const std::wstring& processName)
{
    PROCESSENTRY32 processInfo;
    processInfo.dwSize = sizeof(processInfo);

    HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if (processesSnapshot == INVALID_HANDLE_VALUE) {
        return 0;
    }

    Process32First(processesSnapshot, &processInfo);
    if (!processName.compare(processInfo.szExeFile))
    {
        CloseHandle(processesSnapshot);
        return processInfo.th32ProcessID;
    }

    while (Process32Next(processesSnapshot, &processInfo))
    {
        if (!processName.compare(processInfo.szExeFile))
        {
            CloseHandle(processesSnapshot);
            return processInfo.th32ProcessID;
        }
    }

    CloseHandle(processesSnapshot);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

用法:

auto processId = FindProcessId(L"blabla.exe");
Run Code Online (Sandbox Code Playgroud)

获取句柄应该是显而易见的,只需调用OpenProcess()或类似操作即可。