title: What Difference Does UseShellExecute Have?
body: <p>I am starting a small console application from within my IIS web application. The code is started from within an app pool using code like this,</p>
  
  <pre><code>Process process = new Process();
  ProcessStartInfo processStartInfo = new ProcessStartInfo();
  
  processStartInfo.CreateNoWindow = true;
  processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
  
  // ..
  
  process.Start();
  </code></pre>
  
  <p>I used to intermittently get an error,</p>
  
  <pre><code>Win32Exception exception has occured  Message: No such interface supported
  ErrorCode: 80004005  NativeErrorCode: 80004002
  </code></pre>
  
  <p>I proved that when this happened the console application wouldn't start at all.</p>
  
  <p>I added to the code above this,</p>
  
  <pre><code>processStartInfo.UseShellExecute = false;
  </code></pre>
  
  <p>And the problem has gone away (so far, fingers crossed). I understand that by making this change it doesn't require a valid desktop context to run, but what exactly does that mean. If that means we cannot run the above code if there is no desktop (which applies to an IIS app pool running with a system user), then why did it used to run sometimes in the past rather than fail every time?</p>
  
  <p>Does anybody have any idea why this would make a difference? What does no interface supported mean in this context?</p>
  
  <p>UPDATE:</p>
  
  <p>I have taken on board everything people have said, and done more research myself. So to summarise if you have UseShellExecute = true (which is the default) then it will call ShellExecuteEX in shell32.dll to execute the process. It will do this actually (copied from the System.dll using ILSpy),</p>
  
  <pre><code>public bool ShellExecuteOnSTAThread()
  {
      if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
      {
          ThreadStart start = new ThreadStart(this.ShellExecuteFunction);
          Thread thread = new Thread(start);
          thread.SetApartmentState(ApartmentState.STA);
          thread.Start();
          thread.Join();
      }
      else
      {
          this.ShellExecuteFunction();
      }
      return this._succeeded;
  }
  </code></pre>
  
  <p>If you have UseShellExecute = false then it will call CreateProcess in kernel32.dll to start the process.</p>
  
  <p>I was wondering if there is a problem with the fact the the code ShellExecuteOnSTAThread above is creating a new thread? Could the app pool reach some limit on the threading which could indirectly cause a Win32Exception?</p>