Run process as administrator from a non-admin application
Asked Answered
O

1

31

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.

Orange answered 4/6, 2013 at 19:47 Comment(4)
Maybe this will help? #133879Outshout
The Verb only works with UseShellExecute set to true.Syneresis
@DarkFalcon That seems to have done it, thanks.Orange
@DarkFalcon You need to set UseShellExecute to true for the Verb to be respected and it must be set to 'false' to redirect standard output. You can't do both.Novelist
A
57

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. YouTube archive 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.
Allout answered 1/1, 2014 at 19:14 Comment(9)
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.Novelist
@Novelist 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.Allout
So there is no way to do this to elevate a process with another users credentials then?Seaborne
@Seaborne 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?Allout
So I need to use an intermediate process with the credentials I want to use, and use this process to call the elevated process?Seaborne
@Seaborne 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.Allout
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.Seaborne
@Seaborne 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.Allout
What if i already am running visual studio with admin rights, do I still need to use UseShellExecute = true ?Matsuyama

© 2022 - 2024 — McMap. All rights reserved.