Elevating process privilege programmatically?

C#.NetWindowsWindows ServicesProcess Elevation

C# Problem Overview


I'm trying to install a service using InstallUtil.exe but invoked through Process.Start. Here's the code:

ProcessStartInfo startInfo = new ProcessStartInfo (m_strInstallUtil, strExePath);
System.Diagnostics.Process.Start (startInfo);

where m_strInstallUtil is the fully qualified path and exe to "InstallUtil.exe" and strExePath is the fully qualified path/name to my service.

Running the command line syntax from an elevated command prompt works; running from my app (using the above code) does not. I assume I'm dealing with some process elevation issue, so how would I run my process in an elevated state? Do I need to look at ShellExecute for this?

This is all on Windows Vista. I am running the process in the VS2008 debugger elevated to admin privilege.

I also tried setting startInfo.Verb = "runas"; but it didn't seem to solve the problem.

C# Solutions


Solution 1 - C#

You can indicate the new process should be started with elevated permissions by setting the Verb property of your startInfo object to 'runas', as follows:

startInfo.Verb = "runas";

This will cause Windows to behave as if the process has been started from Explorer with the "Run as Administrator" menu command.

This does mean the UAC prompt will come up and will need to be acknowledged by the user: if this is undesirable (for example because it would happen in the middle of a lengthy process), you'll need to run your entire host process with elevated permissions by Create and Embed an Application Manifest (UAC) to require the 'highestAvailable' execution level: this will cause the UAC prompt to appear as soon as your app is started, and cause all child processes to run with elevated permissions without additional prompting.

Edit: I see you just edited your question to state that "runas" didn't work for you. That's really strange, as it should (and does for me in several production apps). Requiring the parent process to run with elevated rights by embedding the manifest should definitely work, though.

Solution 2 - C#

This code puts the above all together and restarts the current wpf app with admin privs:

if (IsAdministrator() == false)
{
	// Restart program and run as admin
	var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
	ProcessStartInfo startInfo = new ProcessStartInfo(exeName);
	startInfo.Verb = "runas";
	System.Diagnostics.Process.Start(startInfo);
	Application.Current.Shutdown();
	return;
}

private static bool IsAdministrator()
{
	WindowsIdentity identity = WindowsIdentity.GetCurrent();
	WindowsPrincipal principal = new WindowsPrincipal(identity);
	return principal.IsInRole(WindowsBuiltInRole.Administrator);
}


// To run as admin, alter exe manifest file after building.
// Or create shortcut with "as admin" checked.
// Or ShellExecute(C# Process.Start) can elevate - use verb "runas".
// Or an elevate vbs script can launch programs as admin.
// (does not work: "runas /user:admin" from cmd-line prompts for admin pass)

Update: The app manifest way is preferred:

Right click project in visual studio, add, new application manifest file, change the file so you have requireAdministrator set as shown in the above.

A problem with the original way: If you put the restart code in app.xaml.cs OnStartup, it still may start the main window briefly even though Shutdown was called. My main window blew up if app.xaml.cs init was not run and in certain race conditions it would do this.

Solution 3 - C#

According to the article Chris Corio: Teach Your Apps To Play Nicely With Windows Vista User Account Control, MSDN Magazine, Jan. 2007, only ShellExecute checks the embedded manifest and prompts the user for elevation if needed, while CreateProcess and other APIs don't. Hope it helps.

See also: same article as .chm.

Solution 4 - C#

[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

This will do it without UAC - no need to start a new process. If the running user is member of Admin group as for my case.

Solution 5 - C#

i know this is a very old post, but i just wanted to share my solution:

System.Diagnostics.ProcessStartInfo StartInfo = new System.Diagnostics.ProcessStartInfo
{
	UseShellExecute = true, //<- for elevation
	Verb = "runas",  //<- for elevation
	WorkingDirectory = Environment.CurrentDirectory,
	FileName = "EDHM_UI_Patcher.exe",
	Arguments = @"\D -FF"
};
System.Diagnostics.Process p = System.Diagnostics.Process.Start(StartInfo);

NOTE: If VisualStudio is already running Elevated then the UAC dialog won't show up, to test it run the exe from the bin folder.

Solution 6 - C#

You should use Impersonation to elevate the state.

WindowsIdentity identity = new WindowsIdentity(accessToken);
WindowsImpersonationContext context = identity.Impersonate();

Don't forget to undo the impersonated context when you are done.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionScott MarloweView Question on Stackoverflow
Solution 1 - C#mdbView Answer on Stackoverflow
Solution 2 - C#Curtis YallopView Answer on Stackoverflow
Solution 3 - C#Yevgeniy ShapiroView Answer on Stackoverflow
Solution 4 - C#hB0View Answer on Stackoverflow
Solution 5 - C#JhollmanView Answer on Stackoverflow
Solution 6 - C#Vijesh VPView Answer on Stackoverflow