任务管理器中notepad.exe的PID与pi.dwProcessId不同

问题描述 投票:0回答:1

我是 C 新手,正在使用 Win32 API 创建一个带有

CreateProcessW()
的进程。这是我的第一个C 程序。它打开
notepad.exe
并使用
dwProcessId
输出进程 ID。但输出的PID始终与我在任务管理器中看到的打开
notepad.exe
进程的PID不同。这是为什么?

C代码:

#include <stdio.h>
#include <windows.h>

int main (void){

    STARTUPINFOW si = { sizeof(si) };
    PROCESS_INFORMATION pi = { 0 };

    if (!CreateProcessW(
        L"C:\\Windows\\System32\\notepad.exe",
        NULL, // Command line arguments
        NULL, // Process security attributes
        NULL, // Thread security attributes
        FALSE, // Handle inheritance
        0, // Creation flags
        NULL, // Environment block
        NULL, // Current directory
        &si, // Startup information
        &pi)) // Process information
    {
        printf("(-) failed to create process, error: %ld\n", GetLastError());
        return EXIT_FAILURE;
    }

    // Print PID
    printf("Process ID: %lu\n", pi.dwProcessId);

    Sleep(9000); // Wait for 5 seconds

    // Close process and thread handles
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return EXIT_SUCCESS;
}

例如,运行时控制台输出为“进程ID:35692”,但在任务管理器中搜索记事本时,显示的PID为20736。

我做错了什么?

c windows winapi
1个回答
0
投票

您观察到的问题可能是由于 Windows 中的以下行为造成的:

理解进程和父进程关系:

  1. 当您调用 CreateProcessW 启动 notepad.exe 时,Windows 可能会启动 初始“存根”或“启动器”进程。这个过程可以创建 子进程(如实际的记事本窗口),有时 主记事本窗口本身将出现在不同的进程 ID 下 在任务管理器中。

  2. 子进程创建:Windows 在创建 notepad.exe 期间可能会启动多个进程。您看到的 pi.dwProcessId 是 对于由CreateProcessW直接创建的进程。然而, 记事本可能会分叉成多个进程,您在其中看到的那个进程 任务管理器可能是一个不同的子进程,特别是在 现代版本的 Windows 中的进程可以产生额外的 工作进程或 UI 进程。

处理方法:

  1. 检查子进程:现代应用程序,包括记事本、 启动后可能会产生额外的子进程。这 CreateProcessW返回的进程ID指的是父进程, 不一定是与主窗口或 UI 关联的窗口。

  2. 调查工具:您可以使用 Process Explorer 等工具(来自 Sysinternals)来观察进程树。流程资源管理器将 显示父进程和子进程。你应该能够 将 notepad.exe 视为返回的 PID 的子进程 创建进程W。

解决方法: 如果您需要任务管理器中显示的记事本窗口的实际进程 ID,您可以在创建记事本窗口后使用窗口句柄检索它:

  1. 您可以使用 FindWindow 来获取记事本窗口句柄。
  2. 使用 GetWindowThreadProcessId 检索关联的进程 ID 有窗户。

以下是对代码的示例修改,用于检索与记事本窗口关联的实际进程 ID:

#include <stdio.h>
#include <windows.h>

int main(void) {
    STARTUPINFOW si = { sizeof(si) };
    PROCESS_INFORMATION pi = { 0 };

    // Create the Notepad process
    if (!CreateProcessW(
            L"C:\\Windows\\System32\\notepad.exe",
            NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        printf("(-) failed to create process, error: %ld\n", GetLastError());
        return EXIT_FAILURE;
    }

    // Print the process ID of the created process
    printf("Created Process ID: %lu\n", pi.dwProcessId);

    // Wait a little to let the window appear
    Sleep(2000);

    // Find the Notepad window (class name "Notepad", or try NULL for any window)
    HWND hwnd = FindWindowW(L"Notepad", NULL);
    if (hwnd == NULL) {
        printf("(-) failed to find Notepad window, error: %ld\n", GetLastError());
    } else {
        // Get the process ID associated with the window
        DWORD windowProcessId;
        GetWindowThreadProcessId(hwnd, &windowProcessId);
        printf("Process ID of Notepad window: %lu\n", windowProcessId);
    }

    // Wait a bit more
    Sleep(9000);

    // Close process and thread handles
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return EXIT_SUCCESS;
}

说明:

  1. FindWindowW:查找正在运行的记事本实例的窗口。
  2. GetWindowThreadProcessId:检索与窗口关联的进程 ID(即您在任务管理器中看到的进程 ID)。

此方法可确保您获得在任务管理器中看到的实际记事本窗口的 PID,而不仅仅是 CreateProcessW 创建的初始进程。

总结: CreateProcessW返回的进程ID是正确的,但它指的是启动记事本的进程。实际的记事本窗口可能与子进程相关联。 要获取您在任务管理器中看到的窗口的 PID,您可以使用 FindWindow 和 GetWindowThreadProcessId 来检索窗口的进程 ID。

© www.soinside.com 2019 - 2024. All rights reserved.