在 CreateProcess 之后调用 GetModuleFileNameEx 时出现 ERROR_INVALID_HANDLE
Posted
技术标签:
【中文标题】在 CreateProcess 之后调用 GetModuleFileNameEx 时出现 ERROR_INVALID_HANDLE【英文标题】:ERROR_INVALID_HANDLE when calling GetModuleFileNameEx after CreateProcess 【发布时间】:2014-07-21 11:23:42 【问题描述】:在成功调用 CreateProcess 后,我尝试使用 GetModuleFileNameEx 获取创建的进程的路径(lpApplicationName 和 lpCommandLine 参数可以变化或为空,因此在这种情况下它们不可靠)。 问题是 GetModuleFileNameEx 因错误 6 (ERROR_INVALID_HANDLE) 而失败,导致其缓冲区中的数据无效。我无法理解原因,因为 CreateProcess 成功并且进程句柄应该已经正确保存在 pi.hProcess 中。
希望您能有所启发,在此先感谢!
编辑:更新:我注意到删除 CREATE_SUSPENDED 也可以解决此问题,但我需要设置该标志。我该怎么办?
// Defining GetModuleFileNameExA function
typedef DWORD (WINAPI *fGetModuleFileNameExA)
(
HANDLE hProcess,
HMODULE hModule,
LPSTR lpFilename,
DWORD nSize
);
//Load dinamically DLL function on program startup:
fGetModuleFileNameExA _GetModuleFileNameExA = (fGetModuleFileNameExA) GetProcAddress( LoadLibraryA("Psapi.dll"), "GetModuleFileNameExA");
// **** OTHER UNRELATED CODE HERE ****
PROCESS_INFORMATION pi;
//This call succeeds
if (!CreateProcessW( ApplicationName,
CommandLine,
NewProcess.lpProcessAttributes,
NewProcess.lpThreadAttributes,
NewProcess.bInheritHandles,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
NULL,
CurrentDirectory,
&NewProcess.bufStartupInfo,
&pi)
) MessageBoxA(0, "Error creating process", "", 0);
char ProcessPath[MAX_PATH];
//Problem here: call fails with error 6
if (!_GetModuleFileNameExA(pi.hProcess, NULL, ProcessPath, MAX_PATH)) GetLastError();
//Invalid data is displayed
MessageBoxA(0, ProcessPath, "GetModuleFileNameEx",0);
【问题讨论】:
删除CREATE_SUSPENDED
似乎是解决方案
如果你创建了暂停,那么还没有模块信息,因为你没有给进程加载任何模块的机会。
既然您显然没有为CreateProcessW
的第一个参数传递NULL,您难道不知道可执行文件的文件名吗?
devblogs.microsoft.com/oldnewthing/20150716-00/?p=45131
【参考方案1】:
来自 MSDN 上的CreateProcess documentation:
请注意,函数在进程完成初始化之前返回。如果找不到所需的 DLL 或无法初始化,则终止进程。要获取进程的终止状态,请调用
GetExitCodeProcess
。...
调用线程可以使用
WaitForInputIdle
函数等待新进程完成其初始化并等待用户输入而没有待处理的输入。这对于父进程和子进程之间的同步很有用,因为 CreateProcess 无需等待新进程完成其初始化即可返回。例如,创建进程会在尝试查找与新进程关联的窗口之前使用 WaitForInputIdle。
Similar question
【讨论】:
以上是关于在 CreateProcess 之后调用 GetModuleFileNameEx 时出现 ERROR_INVALID_HANDLE的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中通过 lpEnvironment 调用 CreateProcess()
如何在 Delphi Prism 中调用函数 CreateProcess?
cmd.exe 在使用 CreateProcess 调用后立即关闭
CreateProcess .. WaitForSingleObject .. CloseHandle 调用的最佳 try..finally 位置