Проблемы перенаправления вывода процессов C# и psexec

Я пытаюсь создать небольшую программу для запуска на централизованном устройстве. Эта программа будет работать

"psexec \ сервер(ы) netstat -na | findstr "ПРОСЛУШИВАНИЕ""

для сбора данных netstat с удаленных узлов (следует перенаправить вывод в строку), затем проанализировать данные и сравнить их с известным списком. Я могу запустить psexec cmd выше без каких-либо проблем из строки cmd, но когда я пытаюсь запустить ту же команду, что и процесс в моей программе C #, данные для анализа не возвращаются. Я вижу, что netstat запускается (мигает окно cmd с результатами netstat), но process.standardoutput не ловит поток. Если я использую в качестве аргумента ping или что-то еще, кроме psexec, поток перехватывается, и результаты отображаются в моем текстовом поле. Я также пытался установить имя файла на psexec.exe и указать аргументы, но я получаю те же результаты. И последнее, но не менее важное: если я запускаю psexec без каких-либо аргументов, я получаю информацию о возврате справки в свое текстовое поле. Это верно, если я запускаю psexec.exe в качестве имени файла ИЛИ если я запускаю cmd.exe в качестве имени файла с "/c psexec", указанным как args.

Я просто пытаюсь получить вывод psexec при локальном выполнении в этот момент. Я позабочусь о psexec для удаленных машин позже. Любая помощь приветствуется.

Вот код:

        System.Diagnostics.Process pProcess = new System.Diagnostics.Process();  
        pProcess.StartInfo.FileName = "cmd.exe";  
        pProcess.StartInfo.Arguments = "/c psexec netstat";  
        pProcess.StartInfo.UseShellExecute = false;  
        pProcess.StartInfo.RedirectStandardOutput = true;     
        pProcess.Start();
        string strOutput = pProcess.StandardOutput.ReadToEnd(); 
        pProcess.WaitForExit();

        if (pProcess.HasExited)
        {
            textBox1.Text = strOutput;
        }
        else
        {
            textBox1.Text = "TIMEOUT FAIL";
        }

person JStillwell    schedule 20.12.2011    source источник
comment
Скорее всего, вы обнаружите, что пример кода по адресу BeginOutputReadLine соответствует помощь.   -  person Conspicuous Compiler    schedule 21.12.2011


Ответы (2)


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

Кроме того, у вас может быть разрыв между «разрядностью» psexec и вашим приложением, если вы работаете в 64-битной ОС. Если это так, измените платформу проекта, чтобы она соответствовала платформе psexec, а не выполняйте сборку с любым ЦП.

person competent_tech    schedule 20.12.2011
comment
Также проверим стандартный вывод ошибок. Psexec является 32-битным (будет работать на 64-битном), и, поскольку я использую VS10 C# Express, у меня возникают трудности с подтверждением платформы, но я предполагаю, что в данном случае это не имеет значения. Машина, которую я использую для разработки/отладки/запуска, 32-битная. - person JStillwell; 22.12.2011
comment
Наткнулся на несколько вещей, которые нужно изменить, но ваша рекомендация по захвату стандартного вывода ошибок была идеальной и хорошим началом. Также необходимо поймать стандартный ввод, если я хочу предоставить учетные данные. Оказывается, информация отправлялась на вывод ошибок, поэтому я знал, что в этот момент psexec не просто поглощал вывод. Добавлены некоторые литералы str и учетные данные для удаленного запуска, работает отлично. Спасибо за помощь. Вот обновленный код: - person JStillwell; 22.12.2011

Наткнулся на несколько вещей, которые нужно изменить, но ваша рекомендация по захвату стандартного вывода ошибок была идеальной и хорошим началом. Оказывается, некоторая информация отправлялась на вывод ошибок (хотя на самом деле это была не ошибка, просто запустите статус 0 из psexec), поэтому я знал, что в тот момент psexec не просто поглощал ВСЕ выходные данные. Как только я начал пытаться передавать удаленные хосты в качестве аргументов, я начал возвращать данные об ошибках пользователя/передачи. Также необходимо перехватывать стандартный ввод, если я хочу предоставить учетные данные для запуска proc. Добавлены некоторые литералы str и учетные данные для удаленного выполнения, работает отлично. Спасибо за помощь. Вот обновленный код -

        System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
        pProcess.StartInfo.Domain = "domain";
        pProcess.StartInfo.UserName = "user with priv";
        pProcess.StartInfo.Password = new System.Security.SecureString();
        char [] pass = textBox3.Text.ToArray();
        for (int x = 0; x < pass.Length; ++x)
        {
            pProcess.StartInfo.Password.AppendChar(pass[x]);
        }
        pProcess.StartInfo.FileName = @"psexec.exe";
        pProcess.StartInfo.Arguments = @"\\remoteHost netstat -ano";
        pProcess.StartInfo.UseShellExecute = false;
        pProcess.StartInfo.RedirectStandardInput = true;
        pProcess.StartInfo.RedirectStandardOutput = true;
        pProcess.StartInfo.RedirectStandardError = true;
        pProcess.Start();
        pProcess.WaitForExit(30000);
        if (!pProcess.HasExited)
        {
            pProcess.Kill();
        }

        string strOutput = pProcess.StandardOutput.ReadToEnd();
        string errOutput = pProcess.StandardError.ReadToEnd();
        textBox1.Text = strOutput;
        textBox2.Text = errOutput;
person JStillwell    schedule 22.12.2011