55

Is it possible to get a C++ application running in Windows to request administrator privileges from the operating system at run time?

I know it can be done at compile time, but can't seem to find anywhere whether it can be done at run time.

Thanks for your help!

EDIT: What if I want the current instance to have elevated privileges? For example, I might have data stored in memory which I want to keep.

JonaGik
  • 1,447
  • 5
  • 24
  • 35
  • 3
    You can start another process using the `runas` verb. – vcsjones Jun 20 '11 at 23:47
  • 2
    Per the edit: looks like you'll need to serialize out the program state so you can read it back into the new process. – Mark Ransom Jun 21 '11 at 02:24
  • Another option -- make the app startable in a special mode where it merely serves as a means to perform tasks requiring elevated privilages, use IPC to communicate the data -- this will have the nice bonus of not restarting the app (UI context is kept) -- and the UAC window will show the same app name (giving a full illusion of privilages being escalated at runtime :)) < /look-ma-we-tricked-Windows > – mlvljr Nov 09 '15 at 21:14
  • 1
    How can it be done at compile time? – MD XF Mar 02 '17 at 23:06
  • @MDXF https://stackoverflow.com/a/19617989/1422096 – Basj Jul 18 '17 at 13:35

5 Answers5

40

If you want the application to always elevate, you can give it a manifest, either by building one in (not compiling technically) or by putting an external manifest in the same folder as the exe. If you want to decide, as a person, to run it elevated, you right click the exe or short cut and choose Run As Administrator. If you are launching it from code, then as @vcsjones comments, you use the runas verb when you launch that process. For example:

ShellExecute( NULL, 
    "runas",  
    "c:\\windows\\notepad.exe",  
    " c:\\temp\\report.txt",     
    NULL,                        // default dir 
    SW_SHOWNORMAL  
); 
Kate Gregory
  • 18,565
  • 8
  • 53
  • 85
  • 4
    +1. You can use the runas to spawn a second copy of the application as an admin, then have the original terminate itself. – Ed Bayiates Jun 21 '11 at 00:33
  • it doesn't work for me :( Maybe its a CPP version problem? Can you tell me which CPP you use? – Jet Apr 12 '14 at 11:55
  • this has worked with every C++ since the Vista timeframe, @Jet. I suggest you ask your own question. Include your code, your C++ compiler and version, and what you mean by "doesn't work". Make sure you tag it UAC. – Kate Gregory Apr 12 '14 at 12:02
  • 1
    i can confirm that this "doesn't work" as is. ShellExecute returns zero, but GetLastError() gives 5 == ACCESS_DENIED. before i go and ask my own question i will investigate further, but figured you should know... – jheriko Jan 14 '15 at 14:28
  • 1
    (actually the runas and admin privileges are a red herring. i get this problem regardless, even if i run the calling app as admin - so i have another problem to solve before writing off this method) – jheriko Jan 14 '15 at 14:53
  • 1
    Having the app run a second copy of itself using `ShellExecute/Ex(runas)` has always worked fine for me. – Remy Lebeau Dec 13 '18 at 20:02
8

Not quite, but you can do the opposite—you can drop privileges if you already have them. So, you can have your program start out running as an Administrator, using one of the methods listed by Kate Gregory. Then, drop your unneeded privileges; see Dropping privileges in C++ on Windows for how to do that.

Community
  • 1
  • 1
Adam Rosenfield
  • 360,316
  • 93
  • 484
  • 571
  • Is there a way to drop the priviledges so that the user doesn't get a UAC prompt when the application is run? (and then reaquire the priviledges later at which point the user would get a UAC prompt) – JonaGik Jun 22 '11 at 04:57
  • 5
    @JonaGik to avoid the UAC prompt, don't start out running elevated. Launch another app (partition your app) elevated on request, or launch another copy of the same app elevated and close the first one, again on request. – Kate Gregory Jan 17 '13 at 21:34
  • 2
    i know it is _POSSIBLE_, but i do not know how, to elevate privs... Windows 7 taskmanager (taskmgr.exe) can do it, at runtime.. internally how? i dunno. open taskmgr.exe as a non-administrator, then go to Processes tab and press the "Show processes from all users" button, then it will request administrator access, at runtime. – hanshenrik Jan 12 '15 at 16:40
  • 3
    @hanshenrik I know it's too late but someone else could find it useful: Task Manager in Windows 7 doesn't elevate at runtime because it's impossible. All it does when you click "Show processes from all users" is it restarts itself elevated. If you show PID column in the Task Manager, you'll `taskmgr.exe` PID changes after it becomes elevated. The magic here is that you don't see elevation request for a known application by Microsoft, it was implemented in Windows 7 to reduce the number of elevation requests compared to Windows Vista. – Alexey Ivanov Jun 04 '15 at 13:58
8

You can elevate a process only during its creation. When a process already runs, there's no way to change its security token: it either runs elevated or not.

If your application needs to perform an administrative task, and it usually runs non-elevated, you have to create another .exe which will request elevation with its manifest. To start a process elevated, you have to use ShellExecute or ShellExecuteEx function. From your main process you will need a way to pass the commands to that new process that will run elevated.


For more information about UAC, read Designing UAC Applications for Windows Vista series.

Alexey Ivanov
  • 10,757
  • 4
  • 36
  • 58
3

Add a manifest file into your EXE as described here.

http://msdn.microsoft.com/en-us/library/bb756929.aspx

selbie
  • 82,148
  • 13
  • 83
  • 154
2

Your process (and threads) have a token assinged to them. That token already have all your groups set up. Under UAC, the Administrator group is disabled. UAC will remove that disabled group so you end up with a full administrator token.

To acheive the same, you must have the TCB priviledge. In other words, to elevate a process at runtime, you will need help from a process running under the SYSTEM account, and Microsoft isn't providing one, nor an API to control the current UAC implementation. Otherwise, it would defeat the purpose.

For the sake of completness, there is a whitelist of process that can perform some elevated operations without prompting. In short, your executable needs :

  • To be signed by Microsoft
  • To perform predefined operations, like with IFileOperation

The best explanation I found is this hack. It has been fixed since then, but is sheds some light on the whole thing.

ixe013
  • 8,508
  • 3
  • 43
  • 68