title: CodedUITest frontend interaction using another local user (impersonation)
body: <p>I am currently doing some maintenance on a C# CodedUITest. It is testing the frontend on our software which is installed in validated mode (=&gt; which means it can only be used by the &quot;ProtectedUser&quot; User and Administrators).
  The problem is that we obviously want to perform some clicks on the interface but we are using our &quot;TestAgent&quot; User who doesn't have the rights to interact with the software's interface. Instead we want to Impersonate the &quot;ProtectedUser&quot; User when interacting with the interface.</p>
  <p>At some point the following code is used:</p>
  <pre><code>using (new TestUtils.Tools.Impersonator(&quot;.&quot;, &quot;ProtectedUser&quot;, &quot;password&quot;))
  {
  Microsoft.VisualStudio.TestTools.UITesting.Mouse.StartDragging(SoftwareBrowserSlider);
  Microsoft.VisualStudio.TestTools.UITesting.Mouse.StopDragging(SoftwareBrowserTreeView, x, y);
  }
  </code></pre>
  <p><strong>My problem is that I can't seem to get the impersonation to work to do frontend interactions such as mouse clicks or drags. But the Impersonator class works just fine when copying or deleting files. Does anyone know if it is even possible to Impersonate another local user and then perform a click or a drag as the said user?</strong></p>
  <p>Here is my Impersonator class:</p>
  <pre><code>public class Impersonator : IDisposable
    {
      public bool isImpersonating { get; private set; }
  
      private const int LOGON32_LOGON_INTERACTIVE = 2;
      private const int LOGON32_PROVIDER_DEFAULT = 0;
  
      #region DllImports
      [DllImport(&quot;advapi32.dll&quot;, SetLastError = true)]
      private static extern int LogonUser(
          string lpszUserName,
          string lpszDomain,
          string lpszPassword,
          int dwLogonType,
          int dwLogonProvider,
          ref IntPtr phToken);
  
      [DllImport(&quot;advapi32.dll&quot;, SetLastError = true)]
      private static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
  
      [DllImport(&quot;advapi32.dll&quot;, CharSet = CharSet.Auto, SetLastError = true)]
      private static extern int DuplicateToken(
          IntPtr hToken,
          int impersonationLevel,
          ref IntPtr hNewToken);
  
      [DllImport(&quot;advapi32.dll&quot;, CharSet = CharSet.Auto, SetLastError = true)]
      private static extern bool RevertToSelf();
  
      [DllImport(&quot;kernel32.dll&quot;, CharSet = CharSet.Auto)]
      private static extern bool CloseHandle(IntPtr handle);
      #endregion
  
      public Impersonator(string domainName = &quot;.&quot;, 
                          string userName = &quot;ProtectedUser&quot;, 
                          string password = &quot;password&quot;)
      {
        ImpersonateValidUser(domainName, userName, password);
      }
  
      public void Dispose()
      {
        UndoImpersonation();
      }
  
      private void ImpersonateValidUser(string domain, string userName, string password)
      {
        IntPtr token = IntPtr.Zero;
        IntPtr tokenDuplicate = IntPtr.Zero;
        try
        {
          if(!RevertToSelf())
          {
            ThrowLastWin32Exception();
          }
  
          if(LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) == 0)
          {
            ThrowLastWin32Exception();
          }
  
          if (DuplicateToken(token, 2, ref tokenDuplicate) == 0)
          {
            ThrowLastWin32Exception();
          }
  
          isImpersonating = ImpersonateLoggedOnUser(tokenDuplicate);
        }
        finally
        {
          if (token != IntPtr.Zero)
          {
            CloseHandle(token);
          }
  
          if (tokenDuplicate != IntPtr.Zero)
          {
            CloseHandle(tokenDuplicate);
          }
        }
      }
  
      private void ThrowLastWin32Exception()
      {
        throw new Win32Exception(Marshal.GetLastWin32Error());
      }
  
      private void UndoImpersonation()
      {
        if (impersonationContext != null)
        {
          impersonationContext.Undo();
        }
      }
    }
  </code></pre>