报告在System.Diagnostics.Process下运行的cmd文件中的错误/故障

时间:2011-09-15 14:29:31

标签: .net c#-4.0 batch-file cmd dos

我目前正在开发自动安装系统。它的工作原理是需要安装的东西与一个管理安装的cmd文件一起打包。如果它是msi或exe,则cmd文件将告诉安装程序它需要的答案,如果是sql脚本,它将在sqlcmd下运行,依此类推。

cmd文件通过以下c#代码运行:

        ProcessStartInfo p = new System.Diagnostics.ProcessStartInfo(filePath + fileToRun);
        p.WorkingDirectory = filePath;
        Process proc = new System.Diagnostics.Process();
        proc.StartInfo = p;

        proc.Start();
        proc.WaitForExit();

这很有效。它做了它应该做的事情。

然而,我遇到的问题是,由于这是自动化的,并且某些组件依赖于先前组件的存在,因此系统确切地知道在给定环境中安装了什么以及什么不安装是至关重要的。因此,如果cmd文件由于某种原因失败,我的C#代码需要知道它。

我无法弄清楚如何做到这一点。 System.Diagnostics.Process似乎隔离了它正在运行的内容,并且不知道它正在运行的进程内发生了什么。指示失败的错误可能来自许多来源 - 可能是cmd文件,sql脚本或安装程序或PowerShell。

那么有什么方法可以让我的代码在进程中发生错误时进行识别并记录下来吗?我可以更改运行代码的cmd文件并尝试在那里拾取错误,但我无法编辑cmd尝试运行的文件。即使我可以隔离cmd文件中的错误,如何将它们报告回C#?

干杯, 马特

1 个答案:

答案 0 :(得分:2)

您可以重定向流程的错误输出,并在您的应用程序中使用它。

p.UseShellExecute = false; // necessary to redirect stderr
p.RedirectStandardError = true;

然后

string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();

或者,如果您可以控制它,您还可以为流程中的失败选择一些有意义的退出代码,然后在c#代码中切换它们。有点像...

switch (proc.ExitCode)
{
   case 1 : 
      // component A has failed
      break;
   case 2 : 
      // component B has failed
      break;
   default:
     // unknown error
}