拡張機能としてサードパーティの親プロセスにロードされる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()に入らないと想定しています(現在、その想定をテストしています)。
問題を回避するためにできることは少なくとも1つあります(スレッドを中断して開始しないでください)が、最初に障害の原因を最初に理解したいと思います。誰かがこれを引き起こす可能性のあるものとそれを修正する方法を知っていますか?