C++ 无法获取进程 ID (窗口)

C++ Can't get process id (windows)

本文关键字:窗口 ID 取进程 获取 C++      更新时间:2023-10-16

我有一个这样的函数,可以通过进程的名称获取进程的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;
}

这里有几个问题。

首先,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。

这是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 );
}