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

时间:2009-05-14 19:12:29

标签: c++ winapi process

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

7 个答案:

答案 0 :(得分:73)

#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;
}

另外,如果您想在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;
}

答案 1 :(得分: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;
}

答案 2 :(得分:11)

有两种基本技巧。第一个使用PSAPI; MSDN的an example使用EnumProcessesOpenProcessEnumProcessModulesGetModuleBaseName

另一个使用Toolhelp,我更喜欢。使用CreateToolhelp32Snapshot获取进程列表的快照,使用Process32FirstProcess32Next遍历它,提供模块名称和进程ID,直到找到所需的进程,然后调用OpenProcess来处理。

答案 3 :(得分:2)

退房:MSDN Article

您可以使用GetModuleName(我认为?)来获取名称并进行检查。

答案 4 :(得分:1)

OpenProcess功能

来自MSDN:

要打开另一个本地进程的句柄并获取完全访问权限,您必须启用SeDebugPrivilege权限。

答案 5 :(得分:1)

可以使用以下代码:

auto processId = FindProcessId(L"blabla.exe");

用法:

{{1}}

获取句柄应该很明显,只需在其上调用OpenProcess()或类似名称即可。

答案 6 :(得分:0)

如果您不介意使用system(),则执行system("taskkill /f /im process.exe")会比其他方法容易得多。