title: Installing PFX certificate on a different user
body: <p>The code below works pefectly to install a pfx on the current user.
  I want to install it on another user, by giving the username and password (without having to log in with that user).
  I did this a while ago with a batch file, how could I do this using C#?</p>
  
  <p>I've tried a few things, including impersonation but couldn't make it work.</p>
  
  <pre><code>X509Certificate2 certificate = new X509Certificate2("C:\\teste\\cert.pfx", "password");
  X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
  store.Open(OpenFlags.ReadWrite);
  store.Add(certificate);
  store.Close();
  </code></pre>
  
  <p><strong>Update:</strong></p>
  
  <p>Thanks to Bill's code, the process is working fine, as long as the users are logged in.
  Once they log off, an exception is thrown when trying to install the pfx. "The system could not find the specified file".
  If the users log back in, it works again!!</p>
  
  <p>This code is very useful as it is, but if it could also work when the users are OFFLINE it would be perfect for the job!
  Is there a way to do it?</p>
  
  <p>Thanks in advance!</p>
  
  <pre><code>// obtains user token
  [DllImport("advapi32.dll", SetLastError = true)]
  public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
      int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
  
  // closes open handes returned by LogonUser
  [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  public extern static bool CloseHandle(IntPtr handle);
  
  public void DoWorkUnderImpersonation() {
      //elevate privileges before doing file copy to handle domain security
      WindowsImpersonationContext impersonationContext = null;
      IntPtr userHandle = IntPtr.Zero;
      const int LOGON32_PROVIDER_DEFAULT = 0;
      const int LOGON32_LOGON_INTERACTIVE = 2;
      string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
      string user = ConfigurationManager.AppSettings["ImpersonationUser"];
      string password = ConfigurationManager.AppSettings["ImpersonationPassword"];
  
      try {
          Console.WriteLine("windows identify before impersonation: " + WindowsIdentity.GetCurrent().Name);
  
          // if domain name was blank, assume local machine
          if (domain == "")
              domain = System.Environment.MachineName;
  
          // Call LogonUser to get a token for the user
          bool loggedOn = LogonUser(user,
                                      domain,
                                      password,
                                      LOGON32_LOGON_INTERACTIVE,
                                      LOGON32_PROVIDER_DEFAULT,
                                      ref userHandle);
  
          if (!loggedOn) {
              Console.WriteLine("Exception impersonating user, error code: " + Marshal.GetLastWin32Error());
              return;
          }
  
          // Begin impersonating the user
          impersonationContext = WindowsIdentity.Impersonate(userHandle);
  
          Console.WriteLine("Main() windows identify after impersonation: " + WindowsIdentity.GetCurrent().Name);
  
          //run the program with elevated privileges (like file copying from a domain server)
          DoWork();
  
      } catch (Exception ex) {
          Console.WriteLine("Exception impersonating user: " + ex.Message);
      } finally {
          // Clean up
          if (impersonationContext != null) {
              impersonationContext.Undo();
          }
  
          if (userHandle != IntPtr.Zero) {
              CloseHandle(userHandle);
          }
      }
  }
  
  
  private void DoWork() {
      //everything in here has elevated privileges
      X509Certificate2 certificate = new X509Certificate2("C:\\teste\\cert.pfx", "password");
      X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
      store.Open(OpenFlags.ReadWrite);
      store.Add(certificate);
      store.Close();
  }
  </code></pre>