6

I want to run cmd.exe as administrator with arguments from C# in order to prevent a UAC popup. This is necessary in order to use it as an automated installation process. The command I am passing in is simply a path to installation file (.exe) with /q for quiet installation.

When I run this code, there is a CMD popup, but it runs as if it didn't execute anything.

public static string ExecuteCommandAsAdmin(string command)
{

    ProcessStartInfo procStartInfo = new ProcessStartInfo()
    {
        RedirectStandardError = true,
        RedirectStandardOutput = true,
        UseShellExecute = false,
        CreateNoWindow = true,
        FileName = "runas.exe",
        Arguments = "/user:Administrator cmd /K " + command
    };

    using (Process proc = new Process())
    {
        proc.StartInfo = procStartInfo;
        proc.Start();

        string output = proc.StandardOutput.ReadToEnd();

        if (string.IsNullOrEmpty(output))
            output = proc.StandardError.ReadToEnd();

        return output;
    }
}
tshepang
  • 12,111
  • 21
  • 91
  • 136
Eric Kim
  • 10,617
  • 4
  • 29
  • 31
  • 3
    and this is why UAC exists, to prevent unwanted/potentially hostile privilege escalation from occurring silently. – Marc B May 13 '13 at 19:32
  • Wouldn't it be easier to elevate the MSI it self: http://stackoverflow.com/questions/8721349/how-do-install-with-elevated-permissions-using-a-wix-installer but remember that you can't skip UAC.... – rene May 13 '13 at 19:36

5 Answers5

8

Those who could not find the solution to their problems i have found this solution for me: On the solution file, choose

Add => New item => Application manifest file

then open it on C#.

enter image description here

On application manifest file rename "asInvoker" as "requireAdministrator". At the end, application manifest file should look like:

enter image description here

Now, build your solution. Then you will be able to open all the apps as administrator rights.

fracz
  • 20,536
  • 18
  • 103
  • 149
6

There is at least one problem with your command, this line:

Arguments = "/user:Administrator cmd /K " + command

Should be:

Arguments = "/user:Administrator \"cmd /K " + command + "\""

Also, this won't work as a fully automated process, because it will ask for the Administrator's password which in Windows Vista and newer is not known.

Rafael
  • 2,827
  • 1
  • 16
  • 17
1

The UAC will pop up depending on the user settings in "User Account Control Settings." A program cannot bypass that. Only if the user has settings of "Never Notify" will your program do what you are trying to do.

edtheprogrammerguy
  • 5,957
  • 6
  • 28
  • 47
  • 2
    Actually "Never Notify" will make the program fail silently. – Rafael May 13 '13 at 19:39
  • According to the MSFT docs: With Never notify, "You won't be notified before any changes are made to your computer. If you're logged on as an administrator, programs can make changes to your computer without you knowing about it." If you're logged on as a standard user, any changes that require the permissions of an administrator will automatically be denied. – edtheprogrammerguy May 13 '13 at 19:41
1

Two solutions: First, you may the user's appdata directory. This will save you from needing admin privileges in the first place. (in a more general approach - think carefully if you really need those privileges)

Another solution us creating a Windows service which would have those privileges. The first installation of that service would require admin privileges, but after that, you can delegate your work to that service.

The second solution is a potentially security breach - so you'll have to think about what that service would be able to do carefully.

Shlomi Borovitz
  • 1,700
  • 9
  • 9
0

I have been using this code:

        string[] commands = File.ReadAllLines(commandFile);
        foreach (string command in commands)
        {
            Process process = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo();
            //startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.WorkingDirectory = @"C:\Windows\System32";
            startInfo.FileName = "cmd.exe";
            startInfo.Arguments = "/user:Administrator \"cmd /K " + command + "\"";
            process.StartInfo = startInfo;
            process.Start();
        }

As you can see: Trying this code from 'Run' in VS will not give admin, But if you compile this program and run it externally as admin it will. I used this batch file to test privilege level.

@echo off
goto check_Permissions

:check_Permissions
echo Administrative permissions required. Detecting permissions...

net session >nul 2>&1
if %errorLevel% == 0 (
    echo Success: Administrative permissions confirmed.
) else (
    echo Failure: Current permissions inadequate.
)

pause >nul