Чтобы запустить cmd как администратор вместе с командой? - PullRequest
8 голосов
/ 30 сентября 2011

Вот мой код:

try
{
    ProcessStartInfo procStartInfo = new ProcessStartInfo(
                                            "cmd.exe", 
                                            "/c " + command);
    procStartInfo.UseShellExecute = true;
    procStartInfo.CreateNoWindow = true;
    procStartInfo.Verb = "runas";
    procStartInfo.Arguments = "/env /user:" + "Administrator" + " cmd" + command;

    ///command contains the command to be executed in cmd
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo = procStartInfo;
    proc.Start();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

Я хочу сохранить

procStartInfo.UseShellExecute = true 
procStartInfo.RedirectStandardInput = false;

Возможно ли выполнить команду без использования process.standardinput? Я пытаюсь выполнить команду, переданную в качестве аргумента, но команда не выполняется.

Ответы [ 2 ]

5 голосов
/ 30 сентября 2011

Как сказал @mtijn, у вас много чего происходит, что вы также переопределите позже. Вы также должны убедиться, что вы избегаете вещей правильно.

Допустим, вы хотите запустить следующую команду с повышенными правами:

dir c:\

Во-первых, если вы просто запустите эту команду через Process.Start(), окно откроется и закроется сразу же, потому что нет ничего, чтобы держать окно открытым. Обрабатывает команду и выходит. Чтобы оставить окно открытым, мы можем заключить команду в отдельное командное окно и использовать переключатель /K, чтобы оно продолжало работать:

cmd /K "dir c:\"

Чтобы запустить эту команду с повышенными правами, мы можем использовать runas.exe так же, как и вы, за исключением того, что нам нужно избегать вещей немного больше. Согласно справочной документации (runas /?) любые кавычки в команде, которую мы передаем runas, должны быть экранированы обратной косой чертой. К сожалению, выполнение вышеуказанной команды дает нам двойную обратную косую черту, которая запутала анализатор cmd, поэтому его тоже нужно экранировать. Таким образом, приведенная выше команда в конечном итоге будет:

cmd /K \"dir c:\\\"

Наконец, используя предоставленный вами синтаксис, мы можем заключить все в команду runas и заключить вышеприведенную команду в следующий набор кавычек:

runas /env /user:Administrator "cmd /K \"dir c:\\\""

Запустите приведенную выше команду из командной строки, чтобы убедиться, что она работает должным образом.

Учитывая все, что финальный код становится легче собирать:

        //Assuming that we want to run the following command:
        //dir c:\

        //The command that we want to run
        string subCommand = @"dir";

        //The arguments to the command that we want to run
        string subCommandArgs = @"c:\";

        //I am wrapping everything in a CMD /K command so that I can see the output and so that it stays up after executing
        //Note: arguments in the sub command need to have their backslashes escaped which is taken care of below
        string subCommandFinal = @"cmd /K \""" + subCommand.Replace(@"\", @"\\") + " " + subCommandArgs.Replace(@"\", @"\\") + @"\""";

        //Run the runas command directly
        ProcessStartInfo procStartInfo = new ProcessStartInfo("runas.exe");
        procStartInfo.UseShellExecute = true;
        procStartInfo.CreateNoWindow = true;

        //Create our arguments
        string finalArgs = @"/env /user:Administrator """ + subCommandFinal + @"""";
        procStartInfo.Arguments = finalArgs;

        //command contains the command to be executed in cmd
        using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
        {
            proc.StartInfo = procStartInfo;
            proc.Start();
        }
1 голос
/ 30 сентября 2011

почему вы инициализируете объект процесса аргументами, а затем переопределяете эти аргументы?и между прочим: последний бит, где вы устанавливаете аргументы, вы объединяете 'command' прямо до 'cmd', это не имеет особого смысла и может быть там, где происходит сбой (похоже, вы пропустили пробел).* Кроме того, в настоящее время вы используете стандартную командную строку, возможно, вы захотите использовать инструмент runas .Вы также можете вызвать runas из командной строки.

Кроме того, почему вы запускаете 'command' из командной строки?почему бы не запустить его непосредственно из Process.Start с предоставленными тут же правами администратора?вот немного псевдокода:

Process p = Process.Start(new ProcessStartInfo()
{
    FileName = <your executable>,
    Arguments = <any arguments>,
    UserName = "Administrator",
    Password = <password>,
    UseShellExecute = false,
    WorkingDirectory = <directory of your executable>
});
...