CreateProcess を使用して、Cygwin の bash.exe 経由で bash スクリプトを呼び出しています。スクリプトは正常に実行され、stdout と stderr をリダイレクトして自分のウィンドウ内に表示することさえできます。唯一の問題は、bash スクリプトの終了コードを取得できないように見えることです。
スクリプトを起動する方法は次のとおりです。
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof(pi) );
STARTUPINFO si;
si.cb = sizeof (STARTUPINFO);
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwX = 0;
si.dwY = 0;
si.dwXSize = 0;
si.dwYSize = 0;
si.dwXCountChars = 0;
si.dwYCountChars = 0;
si.dwFillAttribute = 0;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.cbReserved2 = 0;
si.lpReserved2 = NULL;
si.hStdOutput = hChildStdOut;
si.hStdInput = NULL;
si.hStdError = hChildStdErr;
CreateProcessW( NULL,
L"bash.exe script.sh file_to_process",
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
hChildProcess = pi.hProcess;
そして、これが私が終了コードを取得しようとしている方法です:
WaitForSingleObject(hChildProcess, 0);
DWORD exitCode = 999;
GetExitCodeProcess(hChildProcess, &exitCode);
DWORD lastError = GetLastError();
スクリプトによって返されるはずの終了コードに関係なく、 exitCode と lastError の両方が常にゼロのようです。
アップデート
cwgem が指摘したように、スクリプトはスクリプトexit
を終了するために使用していました。return
それらをすべて、スクリプトによって返される値ではない exitCode = 1 に変更しようとしました。少しグーグルで調べたところ$(exit n)
、うまくいきましたが、スクリプトから最終的な終了コードしか取得できませんでした (現在、テスト用に 7 ですが、通常は 0 になります)。
たとえば、スクリプトに次のブロックがあります。
if [ `/cygdrive/c/cygwin/bin/find $root -name '*.xml' | grep -c .xml` -eq 0 ] ; then
echo No XMLs present in $root!
$(exit 2)
fi
このパスをテストすると、予想どおり stdout に「No XMLs」というメッセージが表示されますが、終了コードとして 2 が表示されません。代わりに 7 を取得します。これは、上で述べたように、スクリプトの最後の exit ステートメントです。
変数を作成して終了コードを保存し、最後にそれを返すことはできますが、実行してはいけないコードを実行する可能性があるため、それは正しい解決策とは思えません。
私はスクリプトの作成者でもメンテナーでもないことに注意してください。アプリケーションからスクリプトを実行するように求められただけです。