Преобразование приложения C #, запускающего команды CMD, в приложение, запускающее команды Powershell с правами администратора - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть приложение Visual Studio, которое запускает серию команд Cmd, используя следующую функцию

public static void AdminEx(string command) //Runs an Administrative Windows Command
    {
        var proc = new System.Diagnostics.ProcessStartInfo();
        proc.UseShellExecute = true;
        proc.WorkingDirectory = @"C:\Windows\System32";
        proc.FileName = @"C:\Windows\System32\cmd.exe";
        proc.Verb = "runas";
        proc.Arguments = "/c " + command;
        proc.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        var p = System.Diagnostics.Process.Start(proc);
        p.WaitForExit();
    }

Мы недавно обновили наш Код и преобразовали его в Powershell.Как бы я изменил эту функцию в соответствии с новым кодом?Это все еще самый эффективный путь?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Полезный ответ Отавио Кальдоназо дает эффективное решение, но стоит объяснить несколько вещей:

  • Если нет проблем с безопасностью (кто-то разместил нестандартный,вредоносный cmd.exe / powershell.exe исполняемый файл в папке, указанной в переменной среды %PATH% / $env:PATH, которая выгружает стандартные исполняемые файлы), проще использовать только исполняемый файл имя файла , т. е. просто cmd.exe / powershell.exe - это также позволяет избежать проблем с нестандартными установками Windows, корень которых not C:\Windows.

    • Также,учитывая, что вы указываете полный путь через .FileName, свойство .WorkingDirectory эффективно игнорируется с .Verb, установленным в runas,потому что .WorkingDirectory тогда на самом деле не устанавливает рабочий каталог , а указывает , где найти исполняемый файл , если указано только по имени - однако поиск выполняется в%PATH% / $env:PATH все еще выполняются.
  • Хотя параметр /c для передачи команды вызываемой оболочке работает и с CLI PowerShell, PowerShell обычно использует sigil - для префикса имен параметров;таким образом,
    -c (сокращение от -Command) - лучший выбор.

    • Кроме того, учитывая, что PowerShell загружает $PROFILE файл инициализации по умолчанию (даже когда вызывается с -Command или -File, хотя это обычно нежелательно), лучше использовать вместо -NoProfile -Command ....
  • Обычно - если вам не нужно нужно повышение (работает как admin ) - в качестве альтернативы - медленный- создание дочернего процесса через powershell.exe, рассмотрите возможность использования PowerShell SDK (API) , что позволяет быстрее в процессе выполнение при одновременном включении более детального захвата выходных потоков (что, кажется, вас не интересует ваш конкретный сценарий;в то время как System.Diagnostics.ProcessStartInfo позволяет вам захватывать выходные данные stdout и stderr через свойства .RedirectStandardOutput и .RedirectStandardError, обратите внимание, что PowerShell имеет дополнительные выходные данные streams ).

Исходя из вышеизложенного, я предлагаю сделать следующее:

var proc = new System.Diagnostics.ProcessStartInfo();
proc.UseShellExecute = true;
proc.Verb = "runas";
proc.FileName = @"powershell.exe";
proc.Arguments = "-NoProfile -Command " + command;
proc.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
var p = System.Diagnostics.Process.Start(proc);
p.WaitForExit();

Или, более кратко:

using System;
using System.Diagnostics;

var proc = new ProcessStartInfo()
{
  UseShellExecute = true,
  Verb = "runas",
  WindowStyle = ProcessWindowStyle.Hidden,
  FileName = "powershell.exe",
  Arguments = "-NoProfile -Command " + command
};
Process.Start(proc).WaitForExit();
0 голосов
/ 20 февраля 2019

Просто измените строку:

proc.FileName = @"C:\Windows\System32\cmd.exe";

На:

proc.FileName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe";

Это сделает ваше программное обеспечение открытым powershell.exe вместо cmd.exe, я не могу сказать, если этоэто лучший способ, но я попробовал здесь, и это сработало для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...