使用命令行脚本或从后台工作程序运行它时的不同行为

时间:2014-10-28 14:12:54

标签: c# winforms batch-file backgroundworker errorlevel

我有一个非常奇怪的问题,需要了解C#的背景工作者。

我想运行一个命令行程序并检查它的ERRORLEVEL。

cmd.exe /c echo Launching the command && COMMAND_TO_RUN & echo Connexion statut : && echo %ERRORLEVEL% && if %ERRORLEVEL% NEQ 0 (echo FAILURE) ELSE (echo SUCCESS))

当命令失败时,ERRORLEVEL得到值-1

当我在cmd.exe中使用此行时,这是有效的。

但是,这就是问题所在。

当我使用后台工作程序来运行此行时,即使COMMAND_TO_RUN失败,ERRORLEVEL也会取值0.

这是我的后台工作代码:

string[] args = { "/c echo Launching the command && COMMAND_TO_RUN  & echo Connexion statut : && echo %ERRORLEVEL% && if %ERRORLEVEL% NEQ 0 (echo FAILURE) ELSE (echo SUCCESS))};
backgroundWorker1.RunWorkerAsync(args);


 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        string[] args = e.Argument as string[];
        System.Diagnostics.Process process = new System.Diagnostics.Process();
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.Arguments = args[0];
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.RedirectStandardInput = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = false;
        process.Start();
        System.IO.StreamReader sOut = process.StandardOutput;

        string tempOut;
        while (!sOut.EndOfStream)
        {
            // using the report progress userstate allow me to catch 
            // the program output in runtime
            tempOut = sOut.ReadLine();
            backgroundWorker1.ReportProgress(1, tempOut);
        }
        process.Close();
    }

那么使用背景工作者会导致ERRORLEVEL的特定值吗?

提前致谢

1 个答案:

答案 0 :(得分:1)

在不了解BackgroundWorker(抱歉)的情况下,命令部分至少存在三个问题:

  1. 取决于真实的COMMAND_TO_RUN,它可能不是在cmd生成的实例中执行的,并且与此无关,生成的cmd实例已经结束执行而没有问题所以你在C#代码中得到的错误级别,cmd的退出代码,可以是0。

  2. 当行被cmd引用时,它会被解析然后执行。在解析阶段,所有变量读取操作都从要执行的命令中删除,并由变量中的值开始执行该行替换。因此,当您运行%errorlevel%时,所有COMMAND_TO_RUN读取(都在同一行中)都不会更改,并且会在命令执行之前返回变量中的值。

  3. 存在连接问题。 A & B用于连接命令执行,即run A, when finished run B。但A && B表示run A and if not errorlevel then run BA && B || C表示run A, if not errorlevel run B, else run C

  4. 尝试这样的事情(dir是失败的命令)

    cmd.exe /c "echo Launching the command & (( dir *.notexist >nul 2>nul  )&&( echo SUCCESS & exit /b 0 )||( echo FAILURE & exit /b 1 ))"