Программно открыть cmd.exe от имени администратора и перенаправить потоки ввода и вывода

109
18 января 2019, 05:10

Пишу небольшую утилиту, которая имеет необходимость раз в несколько секунд выполнять какую-либо команду командной строке Windows от имени администратора. Создавать для каждой команды новый процесс слишком тяжеловесно, а при попытке перенаправить потоки I/O получаю пустую строку. Можно ли как-то программно опрашивать командную строку от имени администратора, выполняя несколько запросов, не привязываясь к аргументам при создании процесса?

 public CmdClient()
    {
        _process = new Process                              
        {
            StartInfo =
            {
                UseShellExecute = false,
                RedirectStandardOutput = true,              
                RedirectStandardInput = true,
                FileName = "cmd.exe",                       
                Arguments = "/c",
                CreateNoWindow = true,
            }
        };
        if (!_process.Start())
        {
            throw new Win32Exception("Process can't be started");
        }
    }
    public string Execute(string query)
    {
        string result;
        using (StreamWriter sw = _process.StandardInput)
        {
            sw.WriteLine(query);
            using (StreamReader sr = _process.StandardOutput)
            {
                result = sr.ReadToEnd(); // пустая строка при любом запросе
            }
        }
        return result;
    }

UPD: Такой подход работает, пока не попытаться запустить cmd на правах администратора (с параметром /c).

Answer 1

Вы не правильно поняли смысл параметра /C. Вот что говорит по этому поводу cmd /?

/C Выполнение указанной команды (строки) с последующим завершением.

Как видите, параметр не имеет ни какого отношения к правам администратора для консоли. Более того, описанная вами "проблема" - это правильное поведение. Процесс cmd запускается, выполняет единственную команду, и завершается. Так как читаете выходной поток вы явно, а не по событию, то к моменту, когда дело доходит до чтения, процесс уже завершен и поток пуст. Если же читать по событию (тык) то вы сможете зафиксировать вывод до завершения процесса консоли, но это не отменяет тот факт, что процесс будет завершен после выполнения единственной команды.

Для повышения прав используйте

startInfo.Verb = "runas";
READ ALSO
Порядок действий метода JsonConvert.DeserializeObject

Порядок действий метода JsonConvert.DeserializeObject

У меня есть классМне нужно делать таких экземпляров много

142
Unixtimestamp в Datetime

Unixtimestamp в Datetime

Есть время 1538122139000Хочу его сконвертировать в DateTime

139
Как достать номер версии и билда приложения с Jenkins?

Как достать номер версии и билда приложения с Jenkins?

У меня есть приложение на c#, которое билдится на JenkinsНомера билдов идут по порядку от 1 до 23 на данный момент

184
Мгновенное создания файла csv

Мгновенное создания файла csv

Мне нужно проверить есть ли файл по пути, если нет то создать его и сразу же добавить туда текст, но вот проблема, файл создается но текст не добавляется...

124