我有一个 DLL 作为扩展加载到第 3 方父进程中。在这个 DLL 中,我使用 CreateProcess API 实例化外部进程(我自己的)。这在 99.999% 的情况下都很好用,但有时这会突然失败并永久停止工作(也许重新启动父进程可以解决这个问题,但这是不可取的,在我解决问题之前我不建议这样做。)即使 CreteProcess() 没有报告错误并且 GetExitCodeProcess() 返回 128,外部进程也不再被调用,失败的症状是。这是我正在做的简化版本:
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
if(!CreateProcess(
NULL, // No module name (use command line).
"<my command line>",
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
CREATE_SUSPENDED, // Create suspended.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi)) // Pointer to PROCESS_INFORMATION structure.
{
// Handle error.
}
else
{
// Do something.
// Resume the external process thread.
DWORD resumeThreadResult = ResumeThread(pi.hThread);
// ResumeThread() returns 1 which is OK
// (it means that the thread was suspended but then restarted)
// Wait for the external process to finish.
DWORD waitForSingelObjectResult = WaitForSingleObject(pi.hProcess, INFINITE);
// WaitForSingleObject() returns 0 which is OK.
// Get the exit code of the external process.
DWORD exitCode;
if(!GetExitCodeProcess(pi.hProcess, &exitCode))
{
// Handle error.
}
else
{
// There is no error but exitCode is 128, a value that
// doesn't exist in the external process (and even if it
// existed it doesn't matter as it isn't being invoked any more)
// Error code 128 is ERROR_WAIT_NO_CHILDREN which would make some
// sense *if* GetExitCodeProcess() returned FALSE and then I were to
// get ERROR_WAIT_NO_CHILDREN with GetLastError()
}
// PROCESS_INFORMATION handles for process and thread are closed.
}
可以从 Windows 资源管理器或命令行手动调用外部进程,它可以自行启动。像这样调用它,在做任何实际工作之前,创建一个日志文件并记录一些关于它的信息。但是像上面描述的那样调用这个日志信息根本不会出现,所以我假设外部进程的主线程永远不会进入 main() (我现在正在测试这个假设。)
我至少可以做一件事来尝试规避问题(而不是启动暂停的线程),但我首先想先了解失败的根源。有谁知道什么可能导致这个以及如何解决它?