У меня есть DLL, которая загружается в сторонний родительский процесс в качестве расширения. Из этой 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() (сейчас я проверяю это предположение).
Есть по крайней мере одна вещь, которую я мог бы сделать, чтобы попытаться обойти проблему (не запускать приостановленный поток), но сначала я хотел бы понять причину сбоя. Кто-нибудь знает, что может быть причиной этого и как это исправить?