My program normally needs to be launched as an elevated process and therefore it contains the usual manifest (...<requestedExecutionLevel level="requireAdministrator"/>...
), so the UAC will pop up when the program is launched. This work fine as intended.
Now under certain conditions I'd like to run that program (programmatically from another unelevated process) as an unelevated process (IOW it should act just as if the manifest would not contain level="requireAdministrator"
).
Is this possible?
CodePudding user response:
For the sake of clarity, lets call the program you want to run X
.
I normally use a 'shim' to launch X
elevated. The shim is just a little program that is marked requireAdministrator
and whose sole purpose is to run X
elevated. X
is then marked asInvoker
and will run elevated (only) when invoked from the shim. You then make the shim the icon that the user clicks on.
Having done all that, you can then run X
unelevated by launching it direct.
I hope that all makes sense! I don't know of any other way.
CodePudding user response:
Raymond Chen covered this topic on his Old New Thing blog:
November 18th, 2013: How can I launch an unelevated process from my elevated process and vice versa?
Going from an unelevated process to an elevated process is easy. You can run a process with elevation by passing the runas verb to ShellExecute or ShellExecuteEx.
Going the other way is trickier. For one thing, it’s really hard to munge your token to remove the elevation nature properly. And for another thing, even if you could do it, it’s not the right thing to do, because the unelevated user may be different from the elevated user.
...
The solution here is to go back to Explorer and ask Explorer to launch the program for you. Since Explorer is running as the original unelevated user, the program (in this case, the Web browser) will run as Bob. This is also important in the case that the handler for the file you want to open runs as an in-process extension rather than as a separate process, for in that case, the attempt to unelevate would be pointless since no new process was created in the first place. (And if the handler for the file tries to communicate with an existing unelevated copy of itself, things may fail because of UIPI.)
April 25th, 2019: How can I launch an unelevated process from my elevated process, redux
There’s another way which is a bit more direct, but it assumes that the thing you want to do can be done with a direct CreateProcess call. In other words, if you need the system to look up the user’s file associations or default browser, then this technique is not for you.
The idea is to take advantage of PROCESS_CREATE_PROCESS access and the accompanying PROC_THREAD_ATTRIBUTE_PARENT_PROCESS process thread attribute:
...
Basically, this lets you tell the CreateProcess function, “Hey, like, um, pretend that other guy over there is creating the process.”
Both blog articles contain full source code examples.