title: Elimininating Process.WaitForExit() / StandardOutput deadlock condition
body: <p>I've read about this <a href="https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standarderror(v=vs.110).aspx" rel="nofollow">deadlock condition</a> that I'm pretty certain is affecting my code (below).  What I don't understand is: this code worked perfectly well running on Windows Server 2003 (.net 2.0) for the past 12 years.  Now we've been trying to move it to Windows Server 2012, where it always deadlocks.</p>
  
  <p>While my DLLs are built for "anyCPU" (still targeting .net 2.0), the executable process being run is absolutely 32-bit, and the move from Server 2003 to Server 2012 goes from a 32-bit to 64-bit OS.</p>
  
  <p>I think I understand what to do to resolve the issue, but does anyone know why this behavior would have changed from Server 2003 to Server 2012?</p>
  
  <pre><code>public string DoMyProcess(string filenameAndPath, string arguments)
  {
      string stdout="";
      int exitCode = 0;               
  
      try 
      {               
          ProcessStartInfo procStartInfo = new ProcessStartInfo();
          procStartInfo.FileName = filenameAndPath;
          procStartInfo.CreateNoWindow = true;
          procStartInfo.Arguments = arguments;            
          procStartInfo.RedirectStandardOutput = true;
          procStartInfo.UseShellExecute = false;
  
          System.Diagnostics.Process theProcess = null;
          try
          {
              theProcess = Process.Start(procStartInfo);
              theProcess.WaitForExit();
  
              exitCode = theProcess.ExitCode;
  
              // moving this ABOVE WaitForExit should eliminate deadlocks
              // But why did it always work on Server 2003 but not on Server 2012?
              stdout = theProcess.StandardOutput.ReadToEnd();
  
          }
          catch (System.Exception e)
          {
              string errMsg = e.Message;
              log_the_error("threw an exception: " + e.Message);
          }                   
      }           
  
      return stdout;
  }
  </code></pre>
  
  <p>UPDATE:</p>
  
  <p>Mystery deadlock still exists, even after changing the above code as recommended:</p>
  
  <pre><code>        try
          {
              theProcess = Process.Start(procStartInfo);
              stdout = theProcess.StandardOutput.ReadToEnd();                     
          }
          catch (System.Exception e)
          {
              string errMsg = e.Message;
              log_the_error("threw an exception: " + e.Message);
          }                   
      }           
  </code></pre>
  
  <p>What other conditions could cause that deadlock?  If I were to examine StandardError, would it reveal anything useful?</p>
  
  <p>UPDATE #2:</p>
  
  <p>FWIW, we have provisioned another Windows Server 2003 (32-bit), which runs IIS 6.  That was the original machine configuration this code ran on for 12 years (with only an occasional deadlock).  Our same code that deadlocks on Server 2012 IIS 8 DOES NOT DEADLOCK on this Server 2003.</p>
  
  <p>We now have our own minimal and complete code that reproduces the issue.  However, the .exe we've licensed that is being executed by the process has confidentiality clauses that prevent us from posting.  I realize that doesn't help the experts here.</p>
  
  <p>THE ONE HINT we've encountered is that when run via the Visual Studio 2013 debugger installed on the actual server, the process doesn't deadlock/hang, while invoking the process from a browser OUTSIDE the server does.  And oddly -- from a browser ON THE 2012 SERVER we can't connect to that test page -- the browser just says "connecting" and eventually times out (however, other sites hosted by the same server / same IIS 8 CAN BE REACHED from a browser on the server!)</p>
  
  <p>Since the same command line parameters manually run from either an admin command shell or a non-admin command shell works perfectly, it's hard to believe it's a 64-bit / WOW64 problem with this 32-bit executable or it's required DLLs.  We continue to search for places our permissions may be causing problems (the process needs to write to a temp folder, which we've placed at c:\temp, for now).</p>