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.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
jkh
  • 3,618
  • 8
  • 38
  • 66
  • Maybe this will help? http://stackoverflow.com/questions/133379/elevating-process-privilege-programatically – emd Jun 04 '13 at 19:48
  • 2
    The `Verb` only works with `UseShellExecute` set to `true`. – Dark Falcon Jun 04 '13 at 19:55
  • @DarkFalcon That seems to have done it, thanks. – jkh Jun 04 '13 at 19:56
  • @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. – Kiquenet Aug 22 '14 at 11:18

1 Answers1

56

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.
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • 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. – Kiquenet Aug 22 '14 at 11:19
  • 1
    @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. – Ian Boyd Aug 22 '14 at 14:30
  • So there is no way to do this to elevate a process with another users credentials then? – Jordan Sep 19 '14 at 14:55
  • @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?](http://blogs.msdn.com/b/cjacks/archive/2010/02/01/why-can-t-i-elevate-my-application-to-run-as-administrator-while-using-createprocesswithlogonw.aspx) – Ian Boyd Sep 29 '14 at 14:50
  • So I need to use an intermediate process with the credentials I want to use, and use this process to call the elevated process? – Jordan Sep 29 '14 at 17:30
  • @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. – Ian Boyd Sep 29 '14 at 20:23
  • 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. – Jordan Sep 30 '14 at 13:02
  • @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. – Ian Boyd Jun 23 '21 at 17:58
  • What if i already am running visual studio with admin rights, do I still need to use `UseShellExecute = true` ? – Wilko van der Veen Nov 17 '21 at 10:46