1

I have a c# application that needs to do some things as an admin (some installation stuff) and then it needs to run another process as a non-admin. I haven't done anything with UAC before, but I assume there must be a way to do this, right?

This also needs to be automated, so assume that the c# app is started with admin credentials.

Basically the program will need to do something like this:

// MUST run this process as admin
Process adminInstall = new Process();
adminInstall.StartInfo.FileName = "install.bat";
adminInstall.Start();
adminInstall.WaitForExit();

// CANNOT run this process as admin
Process nonAdminProcess = new Process();
nonAdminProcess.StartInfo.FileName = "runner.cmd";
nonAdminProcess.StartInfo.UseShellExecute = false;
nonAdminProcess.StartInfo.RedirectStandardOutput = true;
nonAdminProcess.OutputDataReceived += new DataReceivedEventHandler(myHandler);
nonAdminProcess.Start();
nonAdminProcess.BeginOutputReadLine();
nonAdminProcess.WaitForExit();
Michael Holman
  • 901
  • 1
  • 10
  • 26
  • 1
    possible duplicate of [How do you de-elevate privileges for a child process](http://stackoverflow.com/questions/1173630/how-do-you-de-elevate-privileges-for-a-child-process) – Sheng Jiang 蒋晟 Jan 07 '13 at 20:16

4 Answers4

3

You can embed a manifest in the executable using MT.exe (manifest tool) in the platform SDK after the binary is compiled, but before it is signed. You also have the option of using a custom manifest within your project properties. Open the project properties, then go to the application tab, then change the manifest option from default manifest, to custom manifest. Visual Studio will add a manifest to your project where you can specify "requireAdministrator" privleges. When your app runs, it will provide a UAC prompt, or ask for credentials if logged on as user. There is a good chance sub process will start as admin as well. Otherwise you will need to launch them with the "runas" verb which is undocumented.

Nick
  • 31
  • 2
  • Better options are listed in this duplicate question [here](http://stackoverflow.com/questions/1173630/how-do-you-de-elevate-privileges-for-a-child-process). – Roman Starkov Nov 18 '16 at 23:07
0

Process.Start parameters has one for Username. See Process.Start reference:

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

John S.
  • 1,937
  • 2
  • 18
  • 28
0

There does not appear to be a nice way of doing this using the .Net classes. However, Process.Start with different credentials with UAC on explains a way of doing it using CreateProcessAsUserW after stealing a handle from another process.

Community
  • 1
  • 1
akton
  • 14,148
  • 3
  • 43
  • 47
0

If the aforementioned methods aren't viable, then you can try my method. But its ugly; you need to get a handle to a non admin process, then use DuplicateTokenEx (p/invoke) to copy its (non admin) privileges, then pass that into CreateProcessAsUser. You first need to identify a non admin process though, there may not be any. The newly created process will be spawned with whatever privileges the token you copied contained, not the token of the parent process.

0_______0
  • 547
  • 3
  • 11
  • You don't have to get a handle to a non-admin process; you can use `SaferComputeTokenFromLevel` to create a non-admin token directly. You also have to remember to use medium integrity level. Full details [here](http://stackoverflow.com/a/40687129/33080). – Roman Starkov Nov 18 '16 at 23:06