如何从.NET应用程序调用控制台应用程序并捕获控制台中生成的所有输出?
(请记住,我不想先将信息保存在文件中,然后重新保存,因为我希望将其作为实时信息接收.)
我正在尝试启动一个进程并捕获输出,已经走了很远的路,但我还没有达到我想要的解决方案.
具体来说,我试图从我正在编写的小型实用程序应用程序重置我的开发机器上的IIS.我通过实验得出结论,安全的方法是通过iisreset.exe在子进程中运行.
如果iisreset.exe在命令提示符下运行,则会在此过程中收到反馈.运行iisreset需要几秒钟,并且会生成几行反馈,其间会有暂停.
我想捕获这些反馈并将其呈现在我的Windows窗体应用程序中(在a中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!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
用这个测试结果证明我在需要时可以直接获取捕获的数据.因此,在某种程度上,似乎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 …Run Code Online (Sandbox Code Playgroud) 我对我正在处理的一些代码有一个不寻常的要求.我正在使用不可靠的第三方库进行一些条形码扫描(它在运行太多次后停止工作).为了解决这个问题,我决定在单独的AppDomain中完成工作,然后在完成后卸载AppDomain.这是我正在做的事情的简单但准确的图片:
string domainID = Guid.NewGuid().ToString();
AppDomainSetup setup = new AppDomainSetup();
AppDomain domain = AppDomain.CreateDomain(domainID, null, setup);
string result = null;
try
{
domain.SetData("stream", stream);
domain.DoCallBack(ScanningContext.DoWork);
result = domain.GetData("result") as string;
}
finally
{
AppDomain.Unload(domain);
}
return result;
public static void DoWork()
{
Stream s = AppDomain.CurrentDomain.GetData("stream") as Stream;
ObjectHandle handle = AppDomain.CurrentDomain.CreateInstance("Scanning",
"Scanner");
Scanning.Scanner scanner = (Scanning.Scanner)handle.Unwrap();
Scanning.Result[] results = scanner.Scan(s);
AppDomain.CurrentDomain.SetData("result", results[0].Text);
}
Run Code Online (Sandbox Code Playgroud)
"Scanner"是我正在使用的库周围的包装类.它位于"扫描"组件中; 一个单独的项目,仅用于此目的.
ScanningContext.DoWork是一个静态方法,位于我的服务程序集中.
我对这种方法的问题是在某些地方存在内存泄漏.内存不断增长和增长(当然,当调用此代码时),直到抛出OutOfMemoryExceptions.
我无法找到泄漏的地方.我的所有溪流都被处理掉了.我的所有字节数组都被清空了.我正在清理列表,过去对我有用的一切.我大约90%确信泄漏与这个AppDomain的东西有关.这是我第一次使用它,所以我可能做错了.
我对AppDomains之外的另一种方法持开放态度.我确实需要能够从"扫描仪"类返回结果,因此产生一个过程不是一种选择.
我编写了一个C++程序(从命令行执行),工作正常.现在我需要将它用于我的C#应用程序.也就是说,我希望我的C++程序的输出可以在我调用C#应用程序时使用.
可能吗?如果是这样,怎么样?
任何链接或帮助将不胜感激.