Проблема запуска команды из C# и захвата StandardOutput
Я пытаюсь запустить утилиту командной строки PCLI.exe из C# и безуспешно. Я создаю объект ProcessStartInfo и установил process.StartInfo.RedirectStandardOutput = true, но когда я пытаюсь прочитать process.StandardOutput, я получаю следующую ошибку:
Message=StandardOut has not been redirected or the process hasn't started yet.
Я даже попытался просто передать вывод моей команды в output.txt, и пока файл создается, он пуст.
Процесс завершается, но на самом деле не выполняет нужный файл, поэтому я пытаюсь захватить StandardOutput, чтобы увидеть, что происходит. Я просто пытаюсь запустить команду get из PVCS, чтобы получить файл из PVCS.
Вот фрагмент моего кода:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new
System.Diagnostics.ProcessStartInfo();
process.StartInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
startInfo.WorkingDirectory = "c:\\gitmover";
startInfo.FileName = "C:\\Program Files (x86)\\Serena\\vm\\win32\\bin\\pcli.exe";
Console.WriteLine("Password:?");
string password = Console.ReadLine();
for (int i = 0; i < revisionsArray.Count(); i++)
{
string fileName = "/" + file.Key.Substring(file.Key.IndexOf("Customers")).Replace('\\','/');
startInfo.Arguments = "get -r" + revisionsArray[i] + " -id\"beng:" + password + "\" -prM:\\Engineering\\SOUP -o -ac:/gitmover -bp'/Customers' -z " + fileName + "> output.txt";
process.StartInfo = startInfo;
process.Start();
string strOutput = process.StandardOutput.ReadToEnd();
//Wait for process to finish
process.WaitForExit();
}
1 ответ
Попробуйте обернуть ваш процесс в using
и использовать StreamReader
читать стандартный вывод.
var start = new ProcessStartInfo
{
FileName = _pathToPythonExecutable,
Arguments = string.Format(" {0}", _pathToPythonCalibratorScript),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
WorkingDirectory = _currentWorkingDirectory
};
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
result = reader.ReadToEnd();
}
}
Я написал код ниже, и он отлично работает для меня. Обратите внимание, что в StandardOutput будут отображаться только те команды с кодом выхода 0, в противном случае вам нужно проверить StandardError.
public class ProcessStarter
{
public static OutputEventArgs execAsync(string exe, string arguments)
{
OutputEventArgs oea = new OutputEventArgs();
try
{
using (Process myProcess = new Process())
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.FileName = exe;
startInfo.Arguments = arguments;
myProcess.StartInfo = startInfo;
myProcess.Start();
oea.Data = myProcess.StandardOutput.ReadToEnd();
oea.ErrorMsg = myProcess.StandardError.ReadToEnd();
myProcess.WaitForExit();
oea.exitCode = myProcess.ExitCode;
}
}catch(Exception e)
{
oea.Data = e.Message;
oea.ExceptionHappened();
}
return oea;
}
}
public class OutputEventArgs
{
public int exitCode { get; set; }
public OutputEventArgs() { Error = false; }
public string Data { get; set; }
public bool Error { get; set; }
public bool ErrorMsg { get; set; }
public void ExceptionHappened()
{
exitCode = int.MinValue;
Error = true;
Data = string.Empty;
}
}
Как это использовать?
string arguments = "get -pr" + tbProjectDatabase.Text.Trim() +
" -id" + tbUsername.Text.Trim() + ":" + tbPassword.Text.Trim() +
" -a'" + pvcsFolder + "' -o -z '" + tbCurrentProjectLocation.Text.Trim() + zipItem.FullNameZip + "'";
oea = ProcessStarter.execAsync("pcli", arguments);