title: Launching the 64 bit version of regedit from a 32 bit program to make a sql alias
body: <p>My app needs to set up a SQL alias when it runs if it detects the alias is not set up. Right now I have it generate a temp Reg File and and run it through regedit.exe, however because my app is 32 bit (it must be as I am interoping with some 32 bit dll's that I can not get 64 bit versions for) windows is doing redirection when I run regedit to the version <code>%windir%\SysWow64\regedit.exe</code> instead of <code>%windir%\regedit.exe</code>. </p>
  
  <p>This causes the keys I attempt to write to <code>[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo]</code> to be redirected to the 32 bit sub folder, and my explicit writes to the 32 bit sub-folder, <code>[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo]</code> I have no clue where they are going.</p>
  
  <p>Normally to get around this you would just use <code>%windir%\sysnative\xxxx.exe</code> but <code>sysnative</code> redirects to the System32 folder not the root windows folder, which is where regedit resides.</p>
  
  <p>Is there a way to solve this issue without writing a custom program to elevate and do it itself?</p>
  
  <hr>
  
  <p>Here is my current code, that is failing.</p>
  
  <pre><code>static void CreateAliases()
  {
      using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
      {
          using (var key = baseKey.OpenSubKey(@"SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo"))
          {
              CheckKeys(key);
          }
      }
      try
      {
          using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
          {
              using (var key = baseKey.OpenSubKey(@"SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo"))
              {
                  CheckKeys(key);
              }
          }
      }
      catch
      {
          //Catch failues if it is 32 bit only.
      }
  }
  
  private static void CheckKeys(RegistryKey key)
  {
      //check to see if the key exists.
      if (key == null)
      {
          AddKeys();
          return;
      }
  
      var value = key.GetValue(@"wi\sql2008");
      if (value == null || value.ToString() != String.Concat("DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2008Port))
      {
          AddKeys();
          return;
      }
  
      value = key.GetValue(@"wi\sql2005");
      if (value == null || value.ToString() != String.Concat("DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2005Port))
      {
          AddKeys();
          return;
      }
  }
  static private void AddKeys()
  {
  
      string file = System.IO.Path.GetTempFileName();
      using(StreamWriter sw = new StreamWriter(file))
      {
          sw.WriteLine("Windows Registry Editor Version 5.00");
          sw.WriteLine();
          sw.WriteLine(@"[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo]");
          sw.WriteLine(String.Concat("\"wi\\\\sql2005\"=\"DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2005Port,'"'));
          sw.WriteLine(String.Concat("\"wi\\\\sql2008\"=\"DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2008Port,'"'));
          sw.WriteLine();
          sw.WriteLine(@"[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo]");
          sw.WriteLine(String.Concat("\"wi\\\\sql2005\"=\"DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2005Port, '"'));
          sw.WriteLine(String.Concat("\"wi\\\\sql2008\"=\"DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2008Port, '"'));
      }
  
      WindowsIdentity identity = WindowsIdentity.GetCurrent();
      WindowsPrincipal principal = new WindowsPrincipal(identity);
      bool IsAdmin = principal.IsInRole("BUILTIN\\Administrators");
  
      string regedit;
  
      if (Environment.Is64BitProcess)
      {
          regedit = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "regedit");
      }
      else
      {
          regedit = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "sysnative", "regedit"); //regedit.exe does not exist in sysnative.
      }
  
      if (IsAdmin)
      {
          var proc = Process.Start(new ProcessStartInfo(regedit, String.Concat("/s ", file)));
          proc.WaitForExit();
      }
      else
      {
          MessageBox.Show("Updating registry keys for WI alias, this must be run as administrator");
          var proc = Process.Start(new ProcessStartInfo(regedit, String.Concat("/s ", file)) { Verb = "runas", UseShellExecute = true });
          proc.WaitForExit();
      }
  
      File.Delete(file);
  
  }
  </code></pre>
  
  <p>Here is the temp file that is being generated.</p>
  
  <pre><code>Windows Registry Editor Version 5.00
  
  [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo]
  "wi\\sql2005"="DBMSSOCN,wi,49224"
  "wi\\sql2008"="DBMSSOCN,wi,49681"
  
  [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo]
  "wi\\sql2005"="DBMSSOCN,wi,49224"
  "wi\\sql2008"="DBMSSOCN,wi,49681"
  </code></pre>