My app runs as requestedExecutionLevel set to highestAvailable.
How do I run a process unelevated?
I tried the following but it didn't work:
Process.Start(new ProcessStartInfo {FileName = "foo.exe", Verb = "open"})
I have tried the following trust levels to start my process using Win32 API but none of them work correctly:
0
1260: This program is blocked by group policy. For more information, contact your system administrator.
0x1000
The application was unable to start correctly (0xc0000142). Click OK to close the application.
0x10000
Process starts then hangs
0x20000
All options are not available
0x40000
Runs as admin
If I run tskill foo from my elevated app, it restarts foo with correct privileges.
What I need is a solution in which I don't have to specify the trust level. The process should start with the correct trust level automatically just like the tskill tool restarts foo.exe in the correct trust level. The user selects and runs foo.exe and so it can be anything.
If I can get the trust level of a process somehow, I can do this easily since foo.exe runs when my app can capture its trust level.
The Win32 Security Management functions provide the capability to create a restricted token with normal user rights; with the token, you can call
CreateProcessAsUserto run the process with that token. Below is a proof of concept that runs cmd.exe as a normal user, regardless of whether the process is run in an elevated context.This approach makes use the following Win32 functions:
SaferIdentifyLevelto indicate the identity level (limited, normal, or elevated). Setting thelevelIdtoSAFER_LEVELID_NORMALUSER(0x20000) provides the normal user level.SaferComputeTokenFromLevelcreates a token for the provided level. PassingNULLto the InAccessToken parameter uses the identity of the current thread.CreateProcessAsUsercreates the process with the provided token. Since the session is already interactive, most of the parameters can be kept at default values. (The third parameter,lpCommandLinecan be provided as a string to specify the command line.)CloseHandle(Kernel32) andSaferCloseLevelto free allocated memory.Finally, the P/Invoke code is below (copied mostly from pinvoke.net):