使用Python ctypes创建调试模式calc.exe进程失败问题排查
问题分析:CreateProcessA启动calc.exe返回ERROR_FILE_NOT_FOUND的原因及解决办法
这段Python代码尝试通过CreateProcessA以调试模式启动C:\Windows\System32\calc.exe,但执行失败,返回错误码2(ERROR_FILE_NOT_FOUND),但目标文件确实存在于系统中。
原代码
from ctypes import * kernel32 = windll.kernel32 WORD = c_ushort DWORD = c_ulong LPBYTE = POINTER(c_ubyte) LPTSTR = POINTER(c_char) HANDLE = c_void_p class STARTUPINFO(Structure): _fields_ = [ ("cb", DWORD), ("lpReserved", LPTSTR), ("lpDesktop", LPTSTR), ("lpTitle", LPTSTR), ("dwX", DWORD), ("dwY", DWORD), ("dwXSize", DWORD), ("dwYSize", DWORD), ("dwXCountChars", DWORD), ("dwYCountChars", DWORD), ("dwFillAttribute",DWORD), ("dwFlags", DWORD), ("wShowWindow", WORD), ("cbReserved2", WORD), ("lpReserved2", LPBYTE), ("hStdInput", HANDLE), ("hStdOutput", HANDLE), ("hStdError", HANDLE), ] class PROCESS_INFORMATION(Structure): _fields_ = [ ("hProcess", HANDLE), ("hThread", HANDLE), ("dwProcessId", DWORD), ("dwThreadId", DWORD), ] DEBUG_PROCESS = 0x00000001 creation_flags = DEBUG_PROCESS startupinfo = STARTUPINFO() startupinfo.dwFlags = 0x1 startupinfo.wShowWindow = 0x0 startupinfo.cb = sizeof(startupinfo) process_information = PROCESS_INFORMATION() result = kernel32.CreateProcessA("C:\\Windows\\System32\\calc.exe", None, None, None, None, creation_flags, None, None, byref(startupinfo), byref(process_information) ) print(result) print(kernel32.GetLastError())
核心原因:WoW64文件系统重定向
如果你的代码是在32位Python解释器中运行,而系统是64位Windows,就会触发Windows的WoW64(Windows-on-Windows 64-bit)文件系统重定向机制:
- 64位Windows的
C:\Windows\System32目录存放64位程序,32位程序访问该路径时,会被系统自动重定向到C:\Windows\SysWOW64(专门存放32位兼容程序的目录)。 - 而64位系统中,
calc.exe通常只存在于64位的System32目录,SysWOW64里没有对应的32位版本(尤其是Windows 10及以后版本),所以CreateProcessA找不到文件,返回错误码2。
能否通过改进路径解决?
可以,有两种路径调整方案:
- 方案1:使用
Sysnative别名绕过重定向
32位程序可以通过C:\Windows\Sysnative这个特殊别名直接访问64位的System32目录,把代码中的路径改成"C:\\Windows\\Sysnative\\calc.exe",就能正确找到64位计算器程序。 - 方案2:指定32位程序目录(仅适用于旧系统)
如果你使用的是Windows 7等较旧的64位系统,32位calc.exe可能存在于C:\Windows\SysWOW64,可以尝试把路径改成"C:\\Windows\\SysWOW64\\calc.exe",但Windows 10及以后版本这个路径大概率无效。
其他可行解决办法
- 改用64位Python解释器运行代码:64位程序访问
System32不会触发重定向,直接就能找到目标文件,无需修改路径。 - 临时关闭WoW64重定向:通过
ctypes调用Wow64DisableWow64FsRedirection和Wow64RevertWow64FsRedirection函数,临时关闭文件系统重定向,执行完CreateProcessA后再恢复。示例代码如下:
# 在调用CreateProcessA前添加以下代码 old_value = c_void_p() kernel32.Wow64DisableWow64FsRedirection(byref(old_value)) # 原CreateProcessA调用代码... # 执行完后恢复重定向 kernel32.Wow64RevertWow64FsRedirection(old_value)
内容的提问来源于stack exchange,提问作者Utkonos
相关产品推荐
相关产品推荐

