gpt4 book ai didi

c# - 同步捕获进程输出(即 "when it happens")

转载 作者:IT王子 更新时间:2023-10-29 04:39:53 26 4
gpt4 key购买 nike

我正在尝试启动一个流程并捕获输出,已经取得了很大进展,但还不是我想要的解决方案。

具体来说,我正在尝试通过我正在编写的一个小型实用程序重置我的开发机器上的 IIS。通过试验,我得出的结论是,执行此操作的安全方法是在子进程中运行 iisreset.exe

如果您在命令提示符下运行 iisreset.exe,您会在此过程中获得反馈。运行 iisreset 需要几秒钟,并生成几行反馈,中间有停顿。

我想捕获此反馈并将其呈现在我的 Windows 窗体应用程序中(在 ListBox 中),我已经成功了。我仍然担心的是,在子进程完成之前我不会得到它。我想在创建行时立即逐行获取子进程的输出。

我试着做我的家庭作业,阅读/测试来自例如这些:

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

为了排除这与 iisreset.exe 特别有关的可能性,我编写了一个生成一些输出的小型控制台应用程序,在中间暂停:

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 输出数据的方式似乎在这里发挥了作用。

这是执行捕获的程序(Windows 窗体应用程序)的代码:

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 的输出在我的应用程序中显示为一行)),我运行了一个调试 session 。没有。 StandardOutput 的事件处理程序被调用多次(iisreset.exe 的每个输出行调用一次),但这些调用在进程退出后突然出现。

如果我可以从 iisreset.exe 获取“当它发生时”的输出,以便我可以将其显示为进度指示,我会很高兴。

我看到另一个线程有相同/相似的问题,Asynchronous capture from a process output not working properly ,但没有解决方案。

我有点难过。

最佳答案

自动刷新 printfs/stdouts

C equivalent of autoflush (flush stdout after each write)?

这救了我的屁股......

关于c# - 同步捕获进程输出(即 "when it happens"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6597800/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com