使用CreateProcessW获取的notepad.exe PID与任务管理器显示不一致的原因
我是C语言新手,正在使用Win32 API的CreateProcessW()函数创建进程,这是我的第一个C程序。程序会启动notepad.exe,并通过pi.dwProcessId输出进程ID,但输出的PID始终与任务管理器中显示的notepad.exe进程PID不同。例如控制台输出为“Process ID: 35692”,但任务管理器中显示的PID是20736。请问我哪里出错了?
用户代码:
#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; }
原因
这是**Windows文件系统重定向(File System Redirector)**导致的:
在64位Windows系统中,32位程序访问C:\Windows\System32目录时,会被系统自动重定向到C:\Windows\SysWOW64(存放32位系统文件的目录)。如果你编译的是32位程序,调用CreateProcessW启动C:\Windows\System32\notepad.exe时,实际启动的是SysWOW64下的32位记事本进程,而你在任务管理器中看到的可能是64位记事本进程,两者PID自然不同。
解决办法
有两种可行方案:
方案1:编译为64位程序
在你的开发环境(如Visual Studio)中,将目标平台从x86切换为x64。编译后的64位程序不会触发文件系统重定向,直接启动System32下的64位记事本,此时输出的PID会和任务管理器显示的完全一致。
方案2:禁用文件系统重定向(仅32位程序适用)
在调用CreateProcessW前,调用Wow64DisableWow64FsRedirection禁用重定向,完成进程创建后再用Wow64RevertWow64FsRedirection恢复,确保程序访问的是真实的System32目录。修改后的代码如下:
#include <stdio.h> #include <windows.h> int main (void){ STARTUPINFOW si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; PVOID oldRedirectionValue = NULL; // 禁用文件系统重定向 if (Wow64DisableWow64FsRedirection(&oldRedirectionValue)) { 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()); // 恢复重定向后退出 Wow64RevertWow64FsRedirection(oldRedirectionValue); return EXIT_FAILURE; } // 恢复文件系统重定向 Wow64RevertWow64FsRedirection(oldRedirectionValue); } else { printf("(-) failed to disable FS redirection, error: %ld\n", GetLastError()); return EXIT_FAILURE; } printf("Process ID: %lu\n", pi.dwProcessId); Sleep(9000); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return EXIT_SUCCESS; }
注意:禁用重定向会影响整个进程的文件系统访问,务必在操作完成后恢复,避免干扰其他功能。
内容的提问来源于stack exchange,提问作者jarvic1207

