【问题标题】:C++ Can't get process id (windows)C ++无法获取进程ID(Windows)
【发布时间】:2015-06-30 20:15:08
【问题描述】:

我有一个这样的函数来通过它的名称获取进程的 id,但是它总是在我尝试的每个进程中返回 0:

DWORD GetProcessId(std::string ProcessName)
{
HANDLE hsnap;
PROCESSENTRY32 pt;
DWORD PiD;
hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pt.dwSize = sizeof(PROCESSENTRY32);
do {
    if (!strcmp(pt.szExeFile, ProcessName.c_str())) {
        CloseHandle(hsnap);
        PiD = pt.th32ProcessID;
        return PiD;
        if (PiD != NULL) {
            return 0;
        }
    }
} while (Process32Next(hsnap, &pt));
return 1;
}

主要功能:

int main()
{
DWORD pid = GetProcessId("calc.exe");
std::cout << pid;
if (pid == 0) { printf("error 1"); getchar(); }//error
return 0;
}

【问题讨论】:

    标签: c++ windows winapi process


    【解决方案1】:

    这里有几个问题。

    首先,GetProcessId 是一个 Windows API 函数的名称,它采用单个 HANDLE 作为参数。 HANDLE 通常定义为void*,这意味着任何指针都将满足函数签名。

    您自己的GetProcessId 接受std::string,但您通过传递一个指向字符串常量的指针来调用它。通常这是可以的,可以从中构造一个std::string,但是因为GetProcessId 的Windows API 版本已经与编译器优先调用的函数签名匹配。所以基本上你自己的函数实际上永远不会被调用。

    您自己的函数也存在一些问题。首先,您通过循环的第一次迭代是与垃圾内存进行比较——您忘记调用Process32First,因此pt 第一次未初始化。其次,如果未找到该进程,则表明您正在泄漏 hsnap 句柄。

    尝试以下方法:

    DWORD MyGetProcessId(LPCTSTR ProcessName) // non-conflicting function name
    {
        PROCESSENTRY32 pt;
        HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        pt.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hsnap, &pt)) { // must call this first
            do {
                if (!lstrcmpi(pt.szExeFile, ProcessName)) {
                    CloseHandle(hsnap);
                    return pt.th32ProcessID;
                }
            } while (Process32Next(hsnap, &pt));
        }
        CloseHandle(hsnap); // close handle on failure
        return 0;
    }
    
    int main()
    {
        DWORD pid = MyGetProcessId(TEXT("calc.exe"));
        std::cout << pid;
        if (pid == 0) { printf("error 1"); getchar(); }//error
        return 0;
    }
    

    编辑:我已将函数更改为不再使用 std::string,使用 lstrcmpi 意味着它将作为 Ansi 或 Unicode 构建工作。正如下面的评论员所建议的那样,这些天你真的应该使用 Unicode。

    【讨论】:

    • strcmp() 也不确定,进程名称不区分大小写。不使用 Unicode 也没有优雅之处。
    • 如果您想比较std::stringconst char *,只需使用==
    • @HansPassant 这些都是 OP 的 cmets,完全重写他的代码不是我的工作。如果我将它切换到 unicode,他几乎肯定会回来说它不起作用,因为他的程序的其余部分是在 ansi 中。
    • 是的,当然,忽略它。
    【解决方案2】:

    这是 c 代码,在 Windows 上运行良好。用进程名调用PID_GetProcessId,返回进程名的进程id

    int PID_GetProcessId(char * name, PDWORD pid)
    {
        DWORD aProcesses[1024], cbNeeded, cProcesses;
        UINT32 i;
    
        if (!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        {
            //Error 
        }
    
        /* Calculate how many process identifiers were returned. */
        cProcesses = cbNeeded / sizeof(DWORD);
    
       /* Print the name and process identifier for each process. */
        for ( i = 0; i < cProcesses; i++ )
        {
            if( aProcesses[i] != 0 )
            {
                if(PID_PrintProcessNameAndID( aProcesses[i], name ) == 1)
                {
                   *pid = aProcesses[i];
                   break;
                }
             }
        }
        return 0;
    }
    
    int PID_PrintProcessNameAndID(DWORD processID,char * name)
    {
    
        char szProcessName[MAX_PATH];
        HANDLE hProcess=NULL;
        char buff[200]="";
    
        hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,FALSE, processID );
        /* Get the process name. */
        if (NULL != hProcess )
        {
            HMODULE hMod;
            DWORD cbNeeded;
    
            if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
            {
                GetModuleBaseNameA( hProcess, hMod, (LPSTR)szProcessName, sizeof(szProcessName)/sizeof(TCHAR) );
            }
        }
        if(lstrcmpiA(szProcessName, name) == 0) 
        {
            CloseHandle(hProcess);
            return 1;
        }
    
        return 0;
    
        CloseHandle( hProcess );
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 2020-11-03
      • 2012-07-27
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 2016-01-20
      相关资源
      最近更新 更多