获取批处理脚本错误代码

时间:2009-04-20 18:54:54

标签: winapi batch-file

我希望Win32进程能够启动外部脚本并能够检索它返回的ERRORLEVEL。

另一种方式很简单。只需在Win32应用中使用退出(错误代码)返回错误代码; ,调用脚本就可以正确设置其ERRORLEVEL值。

但是,从Win32调用应用程序,获取脚本错误代码并不完全相同。

我尝试使用CreateProcess()并调用GetExitCodeProcess(),但它总是返回0而不是ERRORLEVEL的实际值。即使我用退出%ERRORLEVEL%

结束我的被调用脚本

我最好的猜测是,脚本不是一个进程。很可能CMD.EXE正在运行,很可能总是以ExitCode为0结束。我知道ERRORLEVEL与进程的ExitCode值不一样,我希望CMD.EXE会镜像它。

编辑:

抱歉,我问过!我刚发现我的问题。我在批处理文件中使用 exit / b errorcode 而不是退出错误代码。似乎/ b选项的优点是只能在从命令行进行测试时关闭正在运行的脚本,而不是CMD.EXE。但缺点是没有为CMD.EXE设置正确的ExitCode。

所以,对后人来说,我在做的是:

int LaunchScript(TCHAR *pCmdLineParam)
{
    bool bResult;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);

    TCHAR   cmdLine[256];
    _tcscpy(cmdLine,L"Test.cmd");
    _tcscat(cmdLine,L" ");
    _tcscat(cmdLine,pCmdLineParam);

    _tprintf(L"Process executing: %s\n",cmdLine);

    bResult = CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)?true:false;
    if (!bResult) {
        _tprintf(L"CreateProcess() error - %d", GetLastError());
        return -1;
    }

    DWORD result = WaitForSingleObject(pi.hProcess,15000);
    if( result == WAIT_TIMEOUT ) {
        return -2;
    }

    DWORD exitCode=0;
    if( !GetExitCodeProcess(pi.hProcess,&exitCode) ) {
        _tprintf(L"GetExitCodeProcess() error - %d", GetLastError());
        return -1;
    }

    _tprintf(L"Process exitcode=%d\n",exitCode);

    return exitCode;
}

我的“入口点”批处理文件如下所示:

@call %*
@exit %ERRORLEVEL%

我正在传递我的脚本作为入口点脚本的参数运行。其他“子脚本”文件可以调用exit / b或exit,因为所有内容都被覆盖。

3 个答案:

答案 0 :(得分:1)

这对我有用:

int DoDOS(string parms)
{

Process p=new Process();
ProcessStartInfo ProcInfo=new ProcessStartInfo();

ProcInfo.Arguments="/C "+parms;
ProcInfo.CreateNoWindow=true;
ProcInfo.ErrorDialog=false;
ProcInfo.ErrorDialogParentHandle=IntPtr.Zero;
ProcInfo.FileName="cmd.exe";
ProcInfo.RedirectStandardError=false;
ProcInfo.RedirectStandardInput=false;
ProcInfo.RedirectStandardOutput=false;
ProcInfo.UseShellExecute=false;
ProcInfo.Verb="";
ProcInfo.WindowStyle=ProcessWindowStyle.Hidden;
p=Process.Start(ProcInfo);

while (!p.HasExited)
      {
      if (laRunning.Text!=RunningTxt) laRunning.Text=RunningTxt;
      else                            laRunning.Text="";
      Application.DoEvents();
      Thread.Sleep(500);
      }

return p.ExitCode; 
}

答案 1 :(得分:1)

只是在黑暗中拍摄(因为我在家,周围没有窗户):

我们在工作中使用'cmd /c call <script>'。也许它适合你的问题。

答案 2 :(得分:-1)

尝试将其作为lpCommandLine的{​​{1}}参数传递:

CreateProcess

它将启用延迟environment variable expansion (否则cmd /v:on /k <script_name> & exit !errorlevel! 在执行%ERRORLEVEL%之前展开)并显式返回脚本返回的<script_name> ERRORLEVEL的返回码。