Run process as administrator from a non-admin application

72,448

You must use ShellExecute. ShellExecute is the only API that knows how to launch Consent.exe in order to elevate.

Sample (.NET) Source Code

In C#, the way you call ShellExecute is to use Process.Start along with UseShellExecute = true:

private void button1_Click(object sender, EventArgs e)
{
   //Public domain; no attribution required.
   ProcessStartInfo info = new ProcessStartInfo(@"C:\Windows\Notepad.exe");
   info.UseShellExecute = true;
   info.Verb = "runas";
   Process.Start(info);
}

If you want to be a good developer, you can catch when the user clicked No:

private void button1_Click(object sender, EventArgs e)
{
   //Public domain; no attribution required.
   const int ERROR_CANCELLED = 1223; //The operation was canceled by the user.

   ProcessStartInfo info = new ProcessStartInfo(@"C:\Windows\Notepad.exe");
   info.UseShellExecute = true;
   info.Verb = "runas";
   try
   {
      Process.Start(info);
   }
   catch (Win32Exception ex)
   {
      if (ex.NativeErrorCode == ERROR_CANCELLED)
         MessageBox.Show("Why you no select Yes?");
      else
         throw;
   }
}

Bonus Watching

  • UAC - What. How. Why.. The architecture of UAC, explaining that CreateProcess cannot do elevation, only create a process. ShellExecute is the one who knows how to launch Consent.exe, and Consent.exe is the one who checks group policy options.
Share:
72,448
jkh
Author by

jkh

Updated on June 24, 2021

Comments

  • jkh
    jkh almost 3 years

    From an application that is not being run as administrator, I have the following code:

    ProcessStartInfo proc = new ProcessStartInfo();
    proc.WindowStyle = ProcessWindowStyle.Normal;
    proc.FileName = myExePath;
    proc.CreateNoWindow = false;
    proc.UseShellExecute = false;
    proc.Verb = "runas";
    

    When I call Process.Start(proc), I do not get a pop up asking for permission to run as administrator, and the exe is not run as administrator.

    I tried adding an app.manifest to the executable found at myExePath, and updated the requestedExecutionLevel to

    <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
    

    With the updated app.manifest, on the Process.Start(proc) call, I get an exception, "The requested operation requires elevation."

    Why isn't the .Verb action not setting administrator privileges?

    I am testing on Windows Server 2008 R2 Standard.

  • Kiquenet
    Kiquenet over 9 years
    I try using UseShellExecute = false; Verb = "runas"; RedirectStandardInput = true; Domain = du[0]; UserName = UserAdministrator; Password = SecureStringHelper.ToSecureString(pwd); LoadUserProfile = true; And using requestedExecutionLevel in manifest. If I use UseShellExecute = true; I get the error The Process object must have the UseShellExecute property set to false in order to start a process as a user.
  • mistertodd
    mistertodd over 9 years
    @Kiquenet You must set UseShellExecute = true. The Windows ShellExecute function is the only function that knows how to launch Consent.exe to prompt for administrator privileges.
  • Jordan
    Jordan over 9 years
    So there is no way to do this to elevate a process with another users credentials then?
  • mistertodd
    mistertodd over 9 years
    @Jordan You can. You launch a non-elevated process as another, using CreateProcessWithLogonW. Then at application will have to call ShellExecute. The reason Microsoft never wrote this as a single function is that it means you are doing something horribly insecure. You must be hard-coding a user's password somewhere. That's very bad. Read: Why Can’t I Elevate My Application to Run As Administrator While Using CreateProcessWithLogonW?
  • Jordan
    Jordan over 9 years
    So I need to use an intermediate process with the credentials I want to use, and use this process to call the elevated process?
  • mistertodd
    mistertodd over 9 years
    @Jordan If you want to run an elevated program as yourself, you can simply use the code in your question (but be sure to set UseShellExecute = true). The question you asked is solved by simply doing that. Your question mentioned nothing about wanting to run an application as a different user. If that is what you want to do instead, then you need to launch the program as the other user, then have ShellExecute elevate it. It's still a bad idea though.
  • Jordan
    Jordan over 9 years
    It may be a bad idea, but my client wants this machine to not have a keyboard on screen or otherwise, they want this interface to be something someone with no computer experience can use, and that to them means hiding anything that's not a button, and the updater I am using requires elevation. Short answer, I have no choice. Thanks for your help. Also, I didn't ask the question.
  • mistertodd
    mistertodd almost 3 years
    @Jordan You don't have to run your code as an adminstrator to update it. During your initial install process, you can adjust the ACLs on your installed Program Files path so that Everyone has Full Control to the folder. This will ensure that any standard user will be able to update your application. It also ensures that any malware will be able to update your application to steal data. It's a terribly stupid idea, but then again clients are terribly stupid.
  • Wilko van der Veen
    Wilko van der Veen over 2 years
    What if i already am running visual studio with admin rights, do I still need to use UseShellExecute = true ?