2013-04-21 81 views
0

我想启动一个cmd文件并立即得到输出。重定向输出的进程

看看我的代码。导入process.WaitForExit()不等;为什么不? copyf.cmd运行良好,如果我不以隐藏模式启动它,因为显示的dosbox运行到cmd的末尾。 在隐藏模式下,cmd被关闭,因为process.WaitForExit()不会完成,直到cmd完成。

public void doSomeThing( Queue<string> output, // queue for output log 
         Queue<string> error // queue for error log 
         ) 
{ 
      String com = "some params"; 

      System.Diagnostics.Process process = new System.Diagnostics.Process(); 
      System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); 
      startInfo.FileName = Properties.Settings.Default.pathTo + @"\Make\copyf.cmd"; 
      startInfo.Arguments = com; 
      startInfo.RedirectStandardOutput = true; 
      startInfo.RedirectStandardError = true; 
      startInfo.UseShellExecute = false; 
      startInfo.CreateNoWindow = true; 
      startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 
      process.StartInfo = startInfo; 

      Thread thread = new Thread(new ThreadStart(() => 
      { 
       String er; 
       String outp; 

       while (true) 
       { 
        outp = process.StandardOutput.ReadLine(); 

        if(outp != null) 
         output.Enqueue("Output :" + outp + "\n"); 

        er = process.StandardError.ReadLine(); 
        if (er != null) 
         error.Enqueue("Error :" + er + "\n"); 
       } 
      })); 

      process.Start(); 
      thread.Start(); 
      process.WaitForExit(); 
} 
+0

为什么你认为'WaitForExit'不等待进程退出? – Ryan 2013-04-21 21:35:51

+0

我发现'.WaitForExit()'不能工作交叉线程,相反我相信我用'while(!proc.HasExited)'(想法比评论更有意思) – Sayse 2013-04-21 21:37:08

+0

好吧,它不是交叉线程。该线程只读取输出/错误。 “进程”runnig在process.WaitForExit(9被调用。 – tux007 2013-04-21 21:39:00

回答

0

您应该使用C开关启动实际控制台命令处理器“cmd.exe”,而不是调用.CMD文件。

/C开关将保持cmd.exe过程一直持续到您的命令文件执行完毕。 WaitForExit()将一直等到CMD.exe完成执行。我曾多次使用它。对于WaitForExit的正确操作,必须在StandardError.ReadToEnd()后调用它。作为described here in msdn修改后的版本如下:

string command = string.Format("{0}\\Make\\copyf.cmd {1}", Properties.Settings.Default.pathTo , com); 
    int waitTime = 60000; //1 min as example here 
    using (var process = new Process() 
    { 
     StartInfo = new ProcessStartInfo() 
       { 
        UseShellExecute = false, 
        RedirectStandardOutput = true, 
        CreateNoWindow = true, 
        RedirectStandardInput = true, 
        RedirectStandardError = true, 
        FileName = "cmd.exe", 
        Arguments = string.Format("/C \"{0}\"", command) 
       } 
    }) 
    { 
     try 
     { 
      if (!process.Start()) 
      { 
       //Log some error "Failed to run command"; 
      } 
     } 
     catch (Exception ex) 
     { 
      //Log some error "Failed to start process command"; 
     } 

     process.BeginOutputReadLine(); 
     string error = process.StandardError.ReadToEnd(); 
     process.WaitForExit(waitTime); 
     if (!process.HasExited) 
     { 
      //Log something "Command: did not finish in time, terminating process" 
      try 
      { 
       process.Kill(); 
      } 
      catch { } 
     } 
    } 
+0

不,它不起作用。 – tux007 2013-04-22 00:47:40

+0

你是说,waitforexit不起作用?或cmd.exe不起作用? – loopedcode 2013-04-22 00:49:55

+0

发布修改后的版本,请注意对StandardError.ReadToEnd()的调用,忘记将它放入我的第一个响应中。 – loopedcode 2013-04-22 01:07:18