获取父进程名称(Windows)

4

我正在尝试在Windows控制台应用程序(C/C++)中获得父进程的名称(完整路径)。看起来应该可以工作,但是它失败了,我无法看到我做错了什么。它成功获取了父PID,但在获取名称时失败。欢迎您提出任何更正意见。

#include <Windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <Psapi.h>

DWORD getParentPID(DWORD pid)
{
    HANDLE h = NULL;
    PROCESSENTRY32 pe = { 0 };
    DWORD ppid = 0;
    pe.dwSize = sizeof(PROCESSENTRY32);
    h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if( Process32First(h, &pe)) 
    {
        do 
        {
            if (pe.th32ProcessID == pid) 
            {
                ppid = pe.th32ParentProcessID;
                break;
            }
        } while( Process32Next(h, &pe));
    }
    CloseHandle(h);
    return (ppid);
}

int getProcessName(DWORD pid, PUCHAR fname, DWORD sz)
{
    HANDLE h = NULL;
    int e = 0;
    h = OpenProcess
    (
        PROCESS_QUERY_INFORMATION,
        FALSE,
        pid
    );
    if (h) 
    {
        if (GetModuleFileNameEx(h, NULL, fname, sz) == 0)
            e = GetLastError();
        CloseHandle(h);
    }
    else
    {
        e = GetLastError();
    }
    return (e);
}

int main(int argc, char *argv[]) 
{
    DWORD pid, ppid;
    int e;
    char fname[MAX_PATH] = {0};
    pid = GetCurrentProcessId();
    ppid = getParentPID(pid);
    e = getProcessName(ppid, fname, MAX_PATH);
    printf("PPID=%d Err=%d EXE={%s}\n", ppid, e, fname);
}

附加信息: OpenProcess返回5(ERROR_ACCESS_DENIED)。如果我添加PROCESS_VM_READ建议,它将返回299(ERROR_PARTIAL_COPY)。我可以打开当前进程,但无法打开父进程。


可能是如何在C++中获取进程名称的重复问题。 - Mekap
到底是哪里出了问题?是调用OpenProcess(h的值是多少)还是GetModuleFileNameEx(e的值是多少)? - Zdeslav Vojkovic
感谢您的回复 - 请查看附加信息。 - Neil Weicher
@Mekap - 这就是一些代码的来源。我可以获取当前进程的名称,但无法获取父进程的名称。 - Neil Weicher
2个回答

5

使用附加的PROCESS_VM_READ标志调用OpenProcess,它应该可以工作:

h = OpenProcess
    (
    PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
    FALSE,
    pid
    );

同时看一下 Mekap 提到的可能重复问题


1
谢谢您的建议。如果我包括PROCESS_VM_READ,那么从OpenProcess返回错误299(ERROR_PARTIAL_COPY)。否则我会得到错误5。 - Neil Weicher
3
请查看GetModuleFileNameEx MSDN文档中的评论:在64位系统上,如果32位进程请求有关64位进程的信息,则此函数返回ERROR_PARTIAL_COPY。在这种情况下,您应该使用QueryProcessFullImageName()(Vista及更高版本)或GetProcessImageFileName()(XP及更高版本)。 - sb9
GetProcessImageFileName是关键。谢谢! - Neil Weicher

5
在Windows Vista+上,您可以使用QueryFullProcessImageName代替GetModuleFileNameEx。然后,只需要使用更少权限的PROCESS_QUERY_LIMITED_INFORMATION标志调用OpenProcess

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接