Проблемы перенаправления вывода процесса C # и psexec - PullRequest
1 голос
/ 21 декабря 2011

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

"psexec \ server (s) netstat -na | findstr" LISTENING ""

для сбора данных 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";
        }

Ответы [ 2 ]

3 голосов
/ 21 декабря 2011

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

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

2 голосов
/ 22 декабря 2011

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

        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;
...