2016-05-17 92 views
0

在控制台应用程序,Windows 10,Visual Studio 2015,.NET 4.6中,我调用Main中的单一方法调用TestProcess。构建模式调试,如果我运行的应用程序而不调试它打印正确的文本:Visual Studio调试 - System.Diagnostics.Process在WaitForExit上挂起

827ccb0eea8a706c4c34a16891f84e7b *test.txt

Press any key to continue . . .

如果我在打印之前调试它等待3秒钟运行的应用程序

Error False False False '' ''

这是真正的问题,只是简化,此代码是一些复杂代码的中坚力量,该代码在md5sums.exe中也没有调试的情况下挂起,但适用于其他一些程序。 Coplex代码也挂在var a = proc.WaitForExit(timeout);直到超时,如附件中的例子。另一方面,这种简化将在没有调试器的情况下发布。而且,所有这些问题都是从Windows 10开始的,在Windows 7上它一切正常。

[编辑]不明白为什么md5sums.exe会导致问题,如果我使用别的东西,即。 FileName =“ping”,参数=“localhost”一切都按预期工作。

[EDIT2]我复杂的程序停止在Windows 10(版本 - 无需调试运行)工作,但这个例子在Windows 7还(调试 - 调试运行)挂

 static void TestProcess() 
     { 
      using (var proc = new Process()) 
      { 
       proc.StartInfo.FileName = "md5sums.exe"; 
       proc.StartInfo.WorkingDirectory = @"C:\Temp\ProcessDebug"; 
       proc.StartInfo.Arguments = "-u test.txt"; 
       proc.StartInfo.CreateNoWindow = true; 
       proc.StartInfo.UseShellExecute = false; 
       proc.StartInfo.RedirectStandardOutput = true; 
       proc.StartInfo.RedirectStandardError = true; 
       StringBuilder output = new StringBuilder(); 
       StringBuilder error = new StringBuilder(); 
       using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false)) 
       using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false)) 
       { 
        proc.OutputDataReceived += (sender, e) => 
        { 
         if (e.Data == null) 
          outputWaitHandle.Set(); 
         else 
          output.AppendLine(e.Data); 
        }; 
        proc.ErrorDataReceived += (sender, e) => 
        { 
         if (e.Data == null) 
          errorWaitHandle.Set(); 
         else 
          error.AppendLine(e.Data); 
        }; 
        proc.Start(); 
        proc.BeginOutputReadLine(); 
        proc.BeginErrorReadLine(); 
        var timeout = 1000; 
        var a = proc.WaitForExit(timeout); 
        var b = outputWaitHandle.WaitOne(timeout); 
        var c = errorWaitHandle.WaitOne(timeout); 
        if (a && b && c) 
         Console.WriteLine(output.ToString()); 
        else 
         Console.WriteLine($"Error {a} {b} {c} '{output}' '{error}'"); 
       } 
      } 
     } 
+0

此问题有一个非常简单的解决方案。当你写一个*有意义的*错误信息时,你只能发现它,这个信息会给你的程序的用户一个很好的提示,说明究竟出了什么问题。一个好的经验法则是,不要在工作站PC上使用少于10秒的超时,在服务器上使用20秒。如果它是一个“复杂”程序,则添加更多内容。 –

+0

@HansPassant复杂的程序在几天内超时:) 20秒超时并没有改变这个例子的行为,虽然test.txt是只有一行短文本和Console.WriteLine的文件($“Error:'{error.ToString ()}','{output.ToString()}'“);返回|“错误:'',''| .a,b和c在失败时都是错误的。什么是有意义的错误信息? – watbywbarif

+1

@watbywbarif尝试禁用VS托管过程,看看会发生什么。 https://msdn.microsoft.com/en-us/library/ms185330.aspx –

回答

1

有3个渔获量解决这个问题:在某些情况下

  • md5sums.exe暂停执行时,与我的设置启动完成之后:

827ccb0eea8a706c4c34a16891f84e7b *test.txt

Press ENTER to exit

如果将CreateNoWindow设置为false并删除标准输出stderr重定向,则可以观察到这一点。这可以通过使用-e开关来解决:'立即退出;在返回之前不要暂停'。这将解决所有情况。但因为我没有使用-e我有不一致的行为取决于调试器和Windows版本。

  • 当没有调试暂停的情况下运行时,虽然所有设置都一样,但没有输出,但“按ENTER退出”。但在调试时运行会导致暂停,以阻止程序,直到超时,其中md5sums将挂起在任务管理器中等待Enter。
  • 在发布模式下,运行时未经调试,虽然暂停激发并且“按ENTER退出”,但在Windows 7上输出了md5sums并继续执行而没有阻止并且超时。在Windows 10上这种情况并非如此,其中md5sum将处于任务管理器中,等待输入并且在超时后继续执行程序。