【问题标题】:Trouble running command from C# and capturing StandardOutput无法从 C# 运行命令并捕获 StandardOutput
【发布时间】:2015-02-26 17:05:45
【问题描述】:

我正在尝试从 C# 运行命令行实用程序 PCLI.exe,但没有运气。我正在构建一个 ProcessStartInfo 对象并设置了 process.StartInfo.RedirectStandardOutput = true,但是当我尝试读取 process.StandardOutput 时出现以下错误:

Message=StandardOut has not been redirected or the process hasn't started yet.

我什至尝试将命令的输出通过管道传输到 output.txt,但在创建文件时它是空的。

该过程已完成,但并未真正执行预期的文件,因此我正在尝试捕获 StandardOutput 以查看发生了什么。仅出于背景目的,我正在尝试运行 PVCS get 命令以从 PVCS 中获取文件。

这是我的代码的 sn-p:

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();
    }

【问题讨论】:

  • 尝试将您的进程放入使用和使用流阅读器来读取标准输出。接听来电!

标签: c# pvcs


【解决方案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();
                    }                  
                }

【讨论】:

  • 输入上面的代码我得到一个编译错误:名称'start'在当前上下文中不存在。另外,如果我在 using 语句中启动进程,如何将 System.Diagnostics.ProcessStartInfo 中的值分配给该进程?
  • 对不起,上面的代码只是一个例子,并不是一个复制和粘贴的解决方案。 Process.Start 接受您的启动选项,即上面代码中的 start。
  • @Ben_G 我已经更新了我的答案,向您展示了 ProcessStartInfo。如果这可以满足您的需求,请告诉我并接受答案。
  • @Ben_G 最终解决了您的问题。将答案标记为已接受也有助于其他有相同问题的人。
  • @DavidWatts:我发现如果 PVCS 退出代码是 0 以外的值,所有结果都将重定向到 StandardError。问题解决了。
【解决方案2】:

我写了下面的代码,它对我来说很好用。请注意,只有退出代码为 0 的命令才会出现在 StandardOutput 中,否则您需要检查 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2017-06-12
    • 1970-01-01
    • 2017-04-28
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多