/ / Jak uzyskać kod wyjścia ze skryptu bash wywołanego za pomocą winApi CreateProcess? - bash, winapi, visual-c ++, proces, cygwin

Jak uzyskać kod wyjścia ze skryptu bash wywoływanego przez winApi CreateProcess? - bash, winapi, visual-c ++, proces, cygwin

Używam CreateProcess do wywołania skryptu bashprzez bash.exe Cygwina. Skrypt działa dobrze, a ja nawet mogę przekierować stdout i stderr, aby wyświetlały się w moim własnym oknie. Jedynym problemem jest to, że nie mogę uzyskać kodu wyjścia skryptu bash.

Oto jak uruchamiam skrypt:

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;

A oto jak próbuję uzyskać kod wyjścia:

WaitForSingleObject(hChildProcess, 0);
DWORD exitCode = 999;
GetExitCodeProcess(hChildProcess, &exitCode);
DWORD lastError = GetLastError();

Zarówno exitCode, jak i lastError wydają się zawsze mieć wartość zero, niezależnie od kodu wyjścia, który powinien zostać zwrócony przez skrypt.

Aktualizacja

Jak zauważył cwgem, skrypt używał exit aby wyjść ze skryptu. Próbowałem zmienić je wszystkie na return, który exitCode = 1, który nie jest wartością zwracaną przez skrypt. Trochę googla dostało mnie $(exit n), który rodzaj działa, ale otrzymuję tylko ostateczny kod wyjścia ze skryptu (obecnie 7 do testowania, ale normalnie byłby 0).

Na przykład w skrypcie mam następujący blok:

if [ `/cygdrive/c/cygwin/bin/find $root -name "*.xml" | grep -c .xml` -eq 0 ] ; then
echo No XMLs present in $root!
$(exit 2)
fi

Kiedy przetestuję tę ścieżkę, otrzymuję komunikat „No XMLs” w stdout, zgodnie z oczekiwaniami, ale nie otrzymuję 2 jako mojego kodu wyjścia, zamiast tego otrzymuję 7, co, jak zauważyłem powyżej, jest końcową instrukcją wyjścia w skrypcie.

Mogę utworzyć zmienną do przechowywania mojego kodu wyjścia i zwrócić go na końcu, ale to nie wydaje się właściwym rozwiązaniem, ponieważ potencjalnie wykonuję kod, którego nie powinienem.

Powinienem chyba zauważyć, że nie jestem autorem ani opiekunem skryptu. Poproszono mnie o uruchomienie go z mojej aplikacji.

Odpowiedzi:

2 dla odpowiedzi № 1

Powinieneś sprawdzić przepływ wykonywania skryptu, ponieważ bash zwróci jako kod wyjścia wartość zwracaną przez polecenie ostatniego uruchomienia, chyba że:

  • Wyjdź zdecydowanie używając exit [returncode]
  • set -e na początku skryptu, który wyjdzie natychmiast, gdy dowolne polecenie zakończy działanie z wartością niezerową