【问题标题】:GetProcessId doesn't find any processGetProcessId 没有找到任何进程
【发布时间】:2021-09-07 06:21:53
【问题描述】:

我正在使用下面的代码尝试获取notepad.exe的PID,但是找不到进程。

我目前在 Windows 10 上运行并使用 VS Studio 19 作为 Release x64 进行编译。

还尝试查找其他进程,如chrome.execalculator.exe等,但找不到任何东西。

DWORD GetProcessId(LPCTSTR ProcessName)
{
    PROCESSENTRY32 pt;
    HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    std::wcout << "Error: " << GetLastError() << std::endl; // Error: 0
    pt.dwSize = sizeof(PROCESSENTRY32);

    std::wcout << "Error: " << GetLastError() << std::endl; // Error: 0

    if (Process32First(hsnap, &pt)) { // must call this first
        do {
            if (!lstrcmpi(pt.szExeFile, ProcessName)) {
                CloseHandle(hsnap);
                return pt.th32ProcessID;
            }
        } while (Process32Next(hsnap, &pt));
    }

    std::wcout << "Error: " << GetLastError() << std::endl; // Error: 24
    CloseHandle(hsnap); // close handle on failure
    return 0;
}



int _tmain(int argc, _TCHAR* argv[])
{

    DWORD processId;

    processId = GetProcessId(TEXT("notepad.exe"));
    std::wcout << "processId: " << processId << std::endl;
    return 0;

}

调试时,我看到代码跳过do while,直接跳转到CloseHandle(hsnap)

GetLastError() 在这一行返回 24。

【问题讨论】:

  • CreateToolhelp32Snapshot 是否失败? Process32First 会失败吗?
  • @Anders 否,GetLastError 都返回 0。
  • GetLastError前需要检查返回值
  • @Anders 你是什么意思? hsnap 不是 NULL 并且 GetLasError 返回 0,Process32First 失败,错误 24,我更新代码,看看。
  • std::wcout 可以重置GetLastError(),所以你需要在API调用失败后立即调用GetLastError(),然后再任何其他系统调用。

标签: c++ winapi


【解决方案1】:

您发布的调试输出窗口图像显示pt.dwSize 设置为2168。这看起来不对。 pt.dwSize 很重要,它被 Windows 用于版本控制。

在我的电脑上sizeof(PROCESSENTRY32)556(这取决于 Windows 版本,我使用的是 Windows 10)。如果项目不是 Unicode,大小应该是那个的一半。在 VS 中,您可以右键单击 PROCESSENTRY32,它会将您带到这个定义:

typedef struct tagPROCESSENTRY32W
{
    DWORD   dwSize;
    DWORD   cntUsage;
    DWORD   th32ProcessID;          // this process
    ULONG_PTR th32DefaultHeapID;
    DWORD   th32ModuleID;           // associated exe
    DWORD   cntThreads;
    DWORD   th32ParentProcessID;    // this process's parent process
    LONG    pcPriClassBase;         // Base priority of process's threads
    DWORD   dwFlags;
    WCHAR   szExeFile[MAX_PATH];    // Path
} PROCESSENTRY32W;

MAX_PATH 应该是 260。我的猜测是您重新定义了MAX_PATH,或者您在某处放置了错误的#pragma 语句。或者发生了一些奇怪的事情。尝试重新启动 Windows(使用重新启动而不是关机/启动)

另外,使用PROCESSENTRY32 pt = {0} 将内存归零

PROCESSENTRY32 pt = { 0 };
pt.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hsnap, &pt))
{
    DWORD err = GetLastError();
    std::cout << "Process32First failed\n";
    std::cout << pt.dwSize << " GetLastError : " << err << "\n";
    CloseHandle(hsnap);
    return DWORD(-1);
}

如 Windows 文档中所示,唯一预期的 GetLastErrorERROR_NO_MORE_FILES。如果错误是其他原因,则表示该功能完全失败。

如果您的项目应该是 Unicode,请考虑避免使用那些 T 宏。只需使用GetProcessId(L"notepad.exe");LPCWSTR 等。

Ps,我运行了您的代码,并且在我的计算机上运行良好。唯一的区别是sizeof(PROCESSENTRY32)

【讨论】:

  • 你说得对,我在MAX_PATH 中有不同的值,我将其更改为260,现在它正在查找进程,谢谢!澄清一下,这个值不能高于260?
猜你喜欢
  • 1970-01-01
  • 2021-10-29
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多