2016-05-17 91 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將處於任務管理器中,等待輸入並且在超時後繼續執行程序。