同步捕获进程的输出(即“发生时”) [英] Capture output of process synchronously (i.e. "when it happens")

查看:117
本文介绍了同步捕获进程的输出(即“发生时”)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图开始一个过程并捕获输出,虽然已经走了很长一段路,但是我并没有完全想要的解决方案。

I am trying to start a process and capture the output, have come a far way, but am not quite at the solution I'd want.

特别是,我正在尝试从正在编写的小型实用程序中重置开发计算机上的IIS。通过实验,我得出结论,这样做的安全方法是在子进程中运行 iisreset.exe

Specifically, I am trying to reset the IIS on my development machine from a small utility application that I am writing. I have come to the conclusion, by experimenting, that the safe way to do this is by running iisreset.exe in a child process.

如果在命令提示符下运行 iisreset.exe ,则会在此过程中获得反馈。运行iisreset需要花费几秒钟的时间,并且会生成几行反馈,中间会有一些暂停。

If you run iisreset.exe on a command prompt, you get feedback during the process. Running iisreset takes several seconds, and several lines of feedback is generated, with pauses in between.

我想捕获此反馈并将其显示在Windows Forms应用程序中(在 ListBox 中),我已经成功了。我仍然担心的是,直到子进程完成,我才能得到它。创建行后,我想逐行从子进程中获取输出。

I'd like to capture this feedback and present it in my Windows Forms application (in a ListBox), and I have succeeded with that. My remaining concern is that I dont get it until the child process finishes. I'd like to get the output from the child process, line by line, immediately when the lines are created.

我试图做作业,例如从这些:

I have tried to do my homework, reading/testing things from e.g. these:

  • How to spawn a process and capture its STDOUT in .NET?
  • Capturing console output from a .NET application (C#)
  • http://www.aspcode.net/ProcessStart-and-redirect-standard-output.aspx

以及其他一些内容相似的文件。大多数(全部?)异步获取输出(例如,使用 Process.ReadToEnd())。我想要同步输出,根据MSDN文档,这涉及建立事件处理程序等,我已经尝试过了。它可以工作,但是直到进程退出后才调用事件处理程序。我从iisreset.exe获得了输出,但是直到它完成为止。

and several more with similar content. Most (all?) get the output asynchronously (e.g. with Process.ReadToEnd()). I want the output synchonously, which acording to the MSDN documentation involves establishing an event handler etc and I've tried that. It works, but the event handler does not get called until the process exits. I get the output from iisreset.exe, but not until it has finished.

要排除这种情况尤其与iisreset.exe有关,我编写了一个小型控制台应用程序,该应用程序生成一些输出,并在以下之间暂停:

To rule out the possibility that this has something to do with iisreset.exe in particular, I wrote a small console application that generates some output, pausing in between:

namespace OutputGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Console.WriteLine("OutputGenerator starting and pausing for 10 seconds..");
            System.Threading.Thread.Sleep(10000);
            System.Console.WriteLine("Pausing for another 10 seconds..");
            System.Threading.Thread.Sleep(10000);
            System.Console.WriteLine("Exiting!");
        }
    }
}

对此进行测试我可以在需要时直接获取捕获的数据。因此,在某种程度上看来iisreset.exe输出数据的方式在这里起作用。

Testing with this it turns out that I get captured data diretly when I want. So, to some extent it seems that the way iisreset.exe outputs the data come into play here.

这是程序(Windows Forms应用程序)的代码,进行捕获:

Here is the code of the program (a Windows Forms application) that does the capture:

using System;
using System.Windows.Forms;
using System.Diagnostics; 

namespace OutputCapturer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            // Running this will show all output after the process has exited
            //String path = @"C:\Windows\system32\iisreset.exe";

            // Running this will show all output "when it happens"
            String path = @"C:\OutputGenerator.exe";

            var p = new Process();
            p.StartInfo.FileName = path;
            p.StartInfo.UseShellExecute = false;  // ShellExecute = true not allowed when output is redirected..
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.CreateNoWindow = true;
            p.OutputDataReceived += OutputDataReceived;
            p.Start();
            p.BeginOutputReadLine();
        }

        private delegate void OutputDataToTextboxDelegate(String s);

        void OutputDataToTextbox(String s)
        {
            tbxOutput.Text += s + Environment.NewLine;
            tbxOutput.Refresh();
        }

        private void OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null && e.Data.ToString() != "")
            {
                // Must run the update of the textbox in the same thread that created it..
                tbxOutput.Invoke(
                    new OutputDataToTextboxDelegate(OutputDataToTextbox), 
                    DateTime.Now.ToString() + ": " + e.Data.ToString()
                );
            }
        }
    }
}

思考这是一个EOL编码问题( iisreset.exe 的输出大约是我的应用程序的一行),我运行了一个调试会话。不。 StandardOutput 的事件处理程序被调用多次( iisreset.exe 中的每个输出行一次),但是这些

Thinking it was an EOL-encoding problem (the output of iisreset.exe apearing as one line to my app)), I ran a debug session. Nope. The event handler for StandardOutput gets called several times (one time for each output line from iisreset.exe), buth these calls come in one burst after the process exits.

如果我能从 iisreset.exe 当它发生时,以便我可以将其显示为进度指示。

I would LOVE if I could get the output from iisreset.exe "when it happens" so that I can show it as a progress indication.

我见过另一个有相同/相似问题的线程,从进程输出中异步捕获无法正常工作,但有解决方案。

I've seen one other thread with the same/similar problem, Asynchronous capture from a process output not working properly , but w/o a solution.

我有点困惑。

推荐答案

对于根据我的具体情况,解决方案就是摩西先生在上面的评论中建议的解决方案,即先运行 iisreset / stop ,然后运行 iisreset / start

For my specific situation, the solution is what Mr Moses suggested in a comment above, i.e. run iisreset /stop followed by iisreset /start.

我需要一个正确的答案,而不是评论,才能将其标记为我的接受的答案,因此这个答案更多的是行政管理,而不是新的贡献。信誉应该交给摩西先生..:-)

I need a proper answer, rather than a comment, in order to mark it as my "accepted answer", so this answer is more of administrativa than a new contribution. The cred should go to Mr Moses.. :-)

这篇关于同步捕获进程的输出(即“发生时”)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆