[c#] How to start a Process as administrator mode in C#

I have a Visual Studio Windows app project. I've added code to download an installer update file. The installer after it has finished downloading would need administrator privileges to run. I have added a manifest file.

When user clicks on the DownloadUpdate.exe, UAC prompts the user for Admin permissions. So I assumed that all processes created and called within DownloadUpdate.exe will run in admin capacity. So I made the setup call my downloaded file with the following code:

Process p = new Process();
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = strFile;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;

This question is related to c# .net

The answer is


You probably need to set your application as an x64 app.

The IIS Snap In only works in 64 bit and doesn't work in 32 bit, and a process spawned from a 32 bit app seems to work to be a 32 bit process and the same goes for 64 bit apps.

Look at: Start process as 64 bit


Here is an example of run process as administrator without Windows Prompt

  Process p = new Process();
  p.StartInfo.FileName = Server.MapPath("process.exe");
  p.StartInfo.Arguments = "";
  p.StartInfo.UseShellExecute = false;
  p.StartInfo.CreateNoWindow = true;
  p.StartInfo.RedirectStandardOutput = true;
  p.StartInfo.Verb = "runas";
  p.Start();
  p.WaitForExit();

Try this:

//Vista or higher check
if (System.Environment.OSVersion.Version.Major >= 6)
{
   p.StartInfo.Verb = "runas";
}

Alternatively, go the manifest route for your application.


This is a clear answer to your question: How do I force my .NET application to run as administrator?

Summary:

Right Click on project -> Add new item -> Application Manifest File

Then in that file change a line like this:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

Compile and run!


Use this method:

public static int RunProcessAsAdmin(string exeName, string parameters)
    {
        try {
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.UseShellExecute = true;
            startInfo.WorkingDirectory = CurrentDirectory;
            startInfo.FileName = Path.Combine(CurrentDirectory, exeName);
            startInfo.Verb = "runas";
            //MLHIDE
            startInfo.Arguments = parameters;
            startInfo.ErrorDialog = true;

            Process process = System.Diagnostics.Process.Start(startInfo);
            process.WaitForExit();
            return process.ExitCode;
        } catch (Win32Exception ex) {
            WriteLog(ex);
            switch (ex.NativeErrorCode) {
                case 1223:
                    return ex.NativeErrorCode;
                default:
                    return ErrorReturnInteger;
            }

        } catch (Exception ex) {
            WriteLog(ex);
            return ErrorReturnInteger;
        }
    }

Hope it helps.


This works when I try it. I double-checked with two sample programs:

using System;
using System.Diagnostics;

namespace ConsoleApplication1 {
  class Program {
    static void Main(string[] args) {
      Process.Start("ConsoleApplication2.exe");
    }
  }
}

using System;
using System.IO;

namespace ConsoleApplication2 {
  class Program {
    static void Main(string[] args) {
      try {
        File.WriteAllText(@"c:\program files\test.txt", "hello world");
      }
      catch (Exception ex) {
        Console.WriteLine(ex.ToString());
        Console.ReadLine();
      }
    }
  }
}

First verified that I get the UAC bomb:

System.UnauthorizedAccessException: Access to the path 'c:\program files\test.txt' is denied.
// etc..

Then added a manifest to ConsoleApplication1 with the phrase:

    <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

No bomb. And a file I can't easily delete :) This is consistent with several previous tests on various machines running Vista and Win7. The started program inherits the security token from the starter program. If the starter has acquired admin privileges, the started program has them as well.


First of all you need to include in your project

using System.Diagnostics;

After that you could write a general method that you could use for different .exe files that you want to use. It would be like below:

public void ExecuteAsAdmin(string fileName)
{
    Process proc = new Process();
    proc.StartInfo.FileName = fileName;
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.Verb = "runas";
    proc.Start();
}

If you want to for example execute notepad.exe then all you do is you call this method:

ExecuteAsAdmin("notepad.exe");

 Process proc = new Process();                                                              
                   ProcessStartInfo info = 
                   new ProcessStartInfo("Your Process name".exe, "Arguments");
                   info.WindowStyle = ProcessWindowStyle.Hidden;
                   info.UseShellExecute =true;
                   info.Verb ="runas";
                   proc.StartInfo = info;
                   proc.Start();

var pass = new SecureString();
pass.AppendChar('s');
pass.AppendChar('e');
pass.AppendChar('c');
pass.AppendChar('r');
pass.AppendChar('e');
pass.AppendChar('t');
Process.Start("notepad", "admin", pass, "");

Works also with ProcessStartInfo:

var psi = new ProcessStartInfo
{
    FileName = "notepad",
    UserName = "admin",
    Domain = "",
    Password = pass,
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true
};
Process.Start(psi);