title: C# Process vs VB6 Shell vs UAC
body: <p>I'm rewriting a small VB6 application/tool whose job is to install the latest version of some legacy VB6 app. The legacy VB6 app is an ActiveX DLL that's built and packaged into an executable installer (some Inno Setup script builds an installer by the name of <code>companynameSetup.exe</code>).</p>
  
  <p>The legacy VB6 app being rewritten:</p>
  
  <ul>
  <li>Kills all processes that consume the ActiveX DLL (across all logged users)</li>
  <li>Uninstalls the current ActiveX DLL</li>
  <li>Installs the new version of the ActiveX DLL</li>
  <li>Can be executed with a command-line argument that disables UI</li>
  </ul>
  
  <p>The rewritten C# app accomplishes all of the above as well. The only difference (apart from the fresh new look), is that regardless of with/without the UI, <strong>the VB6 code does not trigger any UAC prompt:</strong> </p>
  
  <pre><code>Shell(pathAndFileName, vbNormalFocus)
  </code></pre>
  
  <p>But this code does bring up UAC for the installer executable (the uninstaller runs first and doesn't prompt):</p>
  
  <pre><code>var startInfo = new ProcessStartInfo(path, args);
  using (var process = Process.Start(startInfo))
  {
      while (!process.HasExited &amp;&amp; _timerTicks &lt; _timeoutTicks) Thread.Sleep(100);
  
      //... (log stuff, handle timeout, etc.)
  }
  </code></pre>
  
  <p>This is the log file after running as a scheduled task:</p>
  
  <pre><code>2013-06-12 21:49:00.8555 | Info | AutoDeploy.App | COMPUTER : somedomain\someadminuser | StartUp. ShowUI=False; TimeOut=100 | 
  ...
  2013-06-12 21:50:40.4447 | Trace | AutoDeploy.App | COMPUTER : somedomain\someadminuser | Installer timer interval has elapsed (ticks: 99). | 
  2013-06-12 21:50:41.4446 | Trace | AutoDeploy.App | COMPUTER : somedomain\someadminuser | Installer timer interval has elapsed (ticks: 100). | 
  2013-06-12 21:50:41.4602 | Warn | AutoDeploy.App | COMPUTER : somedomain\someadminuser | Process execution has timed out. Process may be hung. | 
  </code></pre>
  
  <p>The process has to be stuck with UAC, because if I run it manually with the GUI, everything runs within a few seconds (after okaying UAC). So VB6 code can run unattended overnight, and the rewritten, new-and-improved (implements logging, failure notifications, all fun stuff!) C# app can't. So how does VB6 go under the radar?</p>
  
  <p>So the question is, <strong>how do I schedule an installer to run unattended, without UAC messing things up</strong>? If scheduling the task is supposed to fix it, then how should the task be set up and is there anything special I need to add/remove from my assembly for it to work?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>The solution was simple:</p>
  
  <pre><code>var startInfo = new ProcessStartInfo(path, args) { UseShellExecute = False };
  </code></pre>