ProcessInfo and RedirectStandardOutput

前端 未结 6 1118
無奈伤痛
無奈伤痛 2020-11-27 16:54

I have an app which calls another process in a command window and that process has updating stats that output to the console window. I thought this was a fairly simple opera

相关标签:
6条回答
  • 2020-11-27 17:03

    flowing code worked in VS2010

    void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (String.IsNullOrEmpty(e.Data) == false)
            {
                new Thread(() =>
                {
                    this.Dispatcher.Invoke(new Action(() =>
                    {
                        // Add you code here
                    }));
                }).Start();
            }
        }
    
    0 讨论(0)
  • 2020-11-27 17:14

    I'm not sure exactly what problem you're running into, but if you're looking to act on output as soon as it's generated, try hooking into the process's OutputDataReceived event. You can specify handlers to receive output asynchronously from the process. I've used this approach successfully.

    Process p = new Process();
    ProcessStartInfo info = p.info;
    info.UseShellExecute = false;
    info.RedirectStandardOutput = true;
    info.RedirectStandardError = true;
    
    p.OutputDataReceived += p_OutputDataReceived;
    p.ErrorDataReceived += p_ErrorDataReceived;
    
    p.Start();
    
    p.BeginOutputReadLine();
    p.BeginErrorReadLine();
    p.WaitForExit();
    

    ..

    void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
      Console.WriteLine("Received from standard out: " + e.Data);
    }
    
    void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
      Console.WriteLine("Received from standard error: " + e.Data);
    }
    

    See the OutputDataReceived event off Process for more information.

    0 讨论(0)
  • 2020-11-27 17:20

    Interestingly you can't read from standard output and standard error at the same time:

    if you redirect both standard output and standard error and then try to read both, for example using the following C# code.

    [C#]

    string output = p.StandardOutput.ReadToEnd();

    string error = p.StandardError.ReadToEnd();

    p.WaitForExit();

    In this case, if the child process writes any text to standard error it will block the process, because the parent process cannot read from standard error until it has finished reading from standard output. However, the parent process will not read from standard output until the process ends. A recommended solution to this situation is to create two threads so that your application can read the output of each stream on a separate thread.

    http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.71).aspx

    0 讨论(0)
  • 2020-11-27 17:23

    I've experienced this before. Sometimes, the way in which the process you're calling outputs to the console is not compatible with this sort of output redirection. I've been fortunate enough in this case to be able to modify the external process to get around this.

    You might try running your code on another process that outputs to the console, and see if it works properly. It reads about right to me right now.

    EDIT:

    I went and pulled a code block I've used to do this. This is in a WPF app which redirects the process output to the window. Notice the event binding. Since this is WPF I have to invoke my call to write the data out. Since you aren't worried about blocking, ou should be able to simply replace that with:

    Console.WriteLine(e.Data);
    

    Hopefully it helps!

        private static void LaunchProcess()
        {
            Process build = new Process();
            build.StartInfo.WorkingDirectory =  @"dir";
            build.StartInfo.Arguments = "";
            build.StartInfo.FileName = "my.exe";
    
            build.StartInfo.UseShellExecute = false;
            build.StartInfo.RedirectStandardOutput = true;
            build.StartInfo.RedirectStandardError = true;
            build.StartInfo.CreateNoWindow = true;
            build.ErrorDataReceived += build_ErrorDataReceived;
            build.OutputDataReceived += build_ErrorDataReceived;
            build.EnableRaisingEvents = true;
            build.Start();
            build.BeginOutputReadLine();
            build.BeginErrorReadLine();
            build.WaitForExit();
        }
    
        // write out info to the display window
        static void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            string strMessage = e.Data;
            if (richTextBox != null && !String.Empty(strMessage))
            {
                App.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Send, (ThreadStart)delegate()
                {
                    Paragraph para = new Paragraph(new Run(strMessage));
                    para.Margin = new Thickness(0);
                    para.Background = brushErrorBrush;
                    box.Document.Blocks.Add(para);
                });
           }
        } 
    
    0 讨论(0)
  • 2020-11-27 17:27

    Using lambda expressions, etc:

    var info = new ProcessStartInfo(path)
    {
        RedirectStandardError = true,
        RedirectStandardOutput = true,
        UseShellExecute = false,
        Verb = "runas",
    };
    
    var process = new Process
    {
        EnableRaisingEvents = true,
        StartInfo = info
    };
    
    Action<object, DataReceivedEventArgs> actionWrite = (sender, e) =>
    {
        Console.WriteLine(e.Data);
    };
    
    process.ErrorDataReceived += (sender, e) => actionWrite(sender, e);
    process.OutputDataReceived += (sender, e) => actionWrite(sender, e);
    
    process.Start();
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();
    process.WaitForExit();
    
    0 讨论(0)
  • 2020-11-27 17:27

    Check that the output you are expecting is not being sent to the StandardError output instead of the StandardOutput output

    0 讨论(0)
提交回复
热议问题