1

我正在使用 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

当我测试这条路径时,我在标准输出中得到了“No XMLs”消息,正如预期的那样,但我没有得到 2 作为我的退出代码。相反,我得到 7,正如我上面提到的,这是脚本中的最终退出语句。

我可以创建一个变量来存储我的退出代码并在最后返回它,但这感觉不是正确的解决方案,因为我可能会执行我不应该执行的代码。

我也许应该注意,我既不是脚本的作者,也不是维护者,我只是被要求从我的应用程序中运行它。

4

1 回答 1

2

您应该检查脚本的执行流程,因为 bash 将作为退出代码返回最后一个运行命令的返回值,除非您:

  • 使用强制退出exit [returncode]
  • set -e在脚本的开头,当任何命令以非零值退出时将立即退出
于 2013-03-09T06:47:36.557 回答