1

When I am trying to start "cmd.exe" as a Administrator, it won't ask for password and I can execute commands.

Below code is working good, but it is asking Admin password.

Is there a way that it should resolve automatically and run under local admin account?

string subCommand = @"dir";
        string subCommandArgs = @"c:\";
        string subCommandFinal = @"cmd /K \""" + subCommand.Replace(@"\", @"\\") + " " + subCommandArgs.Replace(@"\", @"\\") + @"\""";
        ProcessStartInfo procStartInfo = new ProcessStartInfo("runas.exe");
        procStartInfo.UseShellExecute = true;
        procStartInfo.CreateNoWindow = true;
        string finalArgs = @"/env /user:Administrator """ + subCommandFinal + @"""";
        procStartInfo.Arguments = finalArgs;
        using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
        {
            proc.StartInfo = procStartInfo;
            proc.Start();
        }
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
user584018
  • 10,186
  • 15
  • 74
  • 160

1 Answers1

1

when starting the program you can test if the program runs as administrator and if not restart it as administrator, whereby the user is asked for pressing ok only once.

    void RestartIfNeeded() {
        if (!IsAdmin() {
            Process p= new Process {
                StartInfo = new ProcessStartInfo {
                    FileName = Process.GetCurrentProcess().MainModule.FileName,
                    Arguments = //parameters here,
                    //Following two lines make process start as admin
                    Verb = "runas";
                    UseShellExecute = true;
                }
            }
            p.Start();
            p.WaitForExit();
            p.Dispose();
            Enviroment.Exit(p.ExitCode)
        }
    }
    bool IsAdmin() {
            try {
                return new WindowsPrincipal(WindowsIdentity.GetCurrent()) 
                    .IsInRole(WindowsBuiltInRole.Administrator);
            }
            catch (Exception) {
                return false;
            }
        }

If your process should start at startup you can use the "Run with highest privileges" function of the windows task scheduler.

                public static bool InitalizeScheduledTask() {
string TaskName=//TaskName here;
                    XNamespace taskNamespace =
                        XNamespace.Get("http://schemas.microsoft.com/windows/2004/02/mit/task");
                    XElement taskContents = new XElement(taskNamespace + "Task", new XAttribute("version", "1.4"),
                        new XElement(taskNamespace + "RegistrationInfo",
                            new XElement(taskNamespace + "Date", DateTimeToWin32Format(DateTime.Now)),
                            new XElement(taskNamespace + "Author", WindowsIdentity.GetCurrent().Name),
                            new XElement(taskNamespace + "Description",
                                "[Description here] "),
                            new XElement(taskNamespace + "URI", $"\\{TaskName}")),
                        new XElement(taskNamespace + "Triggers",
                            new XElement(taskNamespace + "LogonTrigger", new XElement(taskNamespace + "Enabled", true))),
                        new XElement(taskNamespace + "Principals",
                            new XElement(taskNamespace + "Principal", new XAttribute("id", "Author"),
                                new XElement(taskNamespace + "GroupId", "S-1-5-32-545"),
                                new XElement(taskNamespace + "RunLevel", "HighestAvailable"))),
                        new XElement(taskNamespace + "Settings",
                            new XElement(taskNamespace + "MultipleInstancesPolicy", "Parallel"),
                            new XElement(taskNamespace + "DisallowStartIfOnBatteries", false),
                            new XElement(taskNamespace + "StopIfGoingOnBatteries", false),
                            new XElement(taskNamespace + "AllowHardTerminate", false),
                            new XElement(taskNamespace + "StartWhenAvailable", false),
                            new XElement(taskNamespace + "RunOnlyIfNetworkAvailable", false),
                            new XElement(taskNamespace + "IdleSettings", new XElement(taskNamespace + "StopOnIdleEnd", true),
                                new XElement(taskNamespace + "RestartOnIdle", false)),
                            new XElement(taskNamespace + "AllowStartOnDemand", true),
                            new XElement(taskNamespace + "Enabled", true), new XElement(taskNamespace + "Hidden", false),
                            new XElement(taskNamespace + "RunOnlyIfIdle", false),
                            new XElement(taskNamespace + "DisallowStartOnRemoteAppSession", false),
                            new XElement(taskNamespace + "UseUnifiedSchedulingEngine", true),
                            new XElement(taskNamespace + "WakeToRun", false),
                            new XElement(taskNamespace + "ExecutionTimeLimit", "PT0S"),
                            new XElement(taskNamespace + "Priority", 7)),
                        new XElement(taskNamespace + "Actions", new XAttribute("Context", "Author"),
                            new XElement(taskNamespace + "Exec",
                                new XElement(taskNamespace + "Command", Process.GetCurrentProcess().MainModule.FileName),
                                new XElement(taskNamespace + "Arguments",//Arguments ))));
                    string taskString = new XDocument(new XDeclaration("1.0", "UTF-16", null),
                        taskContents).ToString();
                string tempLocation = Path.Combine(Path.GetTempPath(),$"{TaskName}.xml");
                    File.WriteAllText(tempLocation, taskString);
/*Run Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "SCHTASKS.exe") with the arguments $"/Create /XML \"{tempLocation}\" /TN {TaskName} /RP * /RU {Environment.UserName}"
I have no time to add that now, in that window you will need to enter your password and you have to be admin*/} 
    public static string DateTimeToWin32Format(DateTime toConvert) =>
                $"{toConvert.Year:0000}-{toConvert.Month:00}-{toConvert.Day:00}T{toConvert.Hour:00}:{toConvert.Minute:00}:{toConvert.Second:00}.{toConvert.Millisecond:000}0000";

Please use that function ONLY if your program runs from a protected installation directory.

Tobias Brohl
  • 479
  • 6
  • 25