【问题标题】:C# Shell - IO redirectionC# Shell - IO 重定向
【发布时间】:2010-11-06 20:14:43
【问题描述】:

我正在用 C# 编写一个替代的 Windows shell,我目前正在实现的功能是将所有 IO 都放在同一个 shell 窗口中 - 即,不在另一个窗口中打开 cmd.exe。

现在,我有一个输出的部分解决方案。这是我的代码(其中 p 是正在运行的进程):

while ( !p.HasExited ) {
    /* ... - irrelevant */
    if ( redirect ) {
        try {
            p.BeginOutputReadLine();
        } catch { }
    }
}

进程设置了所有正确的属性,例如UseShellExecute = FalseRedirectStandard{Input, Output, Error} = True,并且事件处理程序设置正确,但不一致。

我已经尝试取出 try/catch(我知道这是非常糟糕的做法),并使用忙布尔,当处理程序运行时设置为 false,但由于某种原因,我仍然在 p 上收到 InvalidOperationException .BeginOutputReadLine() - 说明已经有一个异步操作在运行。

任何帮助都将不胜感激,即使它需要与上述解决方案完全不同的解决方案,而不仅仅是修复它。

谢谢。

编辑:这是启动该过程的代码:

if (redirect)
{
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.RedirectStandardError = true;
    p.StartInfo.RedirectStandardInput = true;
    p.StartInfo.UseShellExecute = false;
    p.OutputDataReceived += new DataReceivedEventHandler(redirectHandler_StdOut);
    p.ErrorDataReceived += new DataReceivedEventHandler(redirectHandler_StdErr);
}
p.Start();

另外,我意识到我并没有解释我所说的不一致是什么意思。正如他们所说,一张照片值得2^3的话:

【问题讨论】:

  • 启动进程的代码是什么样的?
  • 我现在就更新问题:)

标签: c# .net io


【解决方案1】:

以 Begin 为前缀的方法通常异步运行。这是你想要的吗?因为看起来循环尽可能快地运行,所以调用越来越多的 BeginOutputReadLine(因为调用立即返回,在它完成之前,循环又开始进行另一次迭代)。

您可以在 StandardOutput 流上调用 ReadLine 以获得同步解决方案。或者:

    while ( !p.HasExited ) {
        /* ... - irrelevant */
        if ( redirect && !busy ) {
            try {
                busy = true;
                p.BeginOutputReadLine();
            } catch { }
        }
    }
   ////In the method that gets called upon completion of BeginOutputReadLine
   busy = false;

请记住这一点(来自 MSDN):

当异步读操作 开始,事件处理程序被调用 每次关联的进程 将一行文本写入其 标准输出流。

您可以取消异步读取 通过调用 CancelOutputRead 进行操作。 可以通过以下方式取消读取操作 调用者或事件处理程序。 取消后可以拨打 BeginOutputReadLine 再次恢复 异步读取操作。

这让我相信你应该只调用这个方法一次,它会在写完一行时通过回调不断通知你。

【讨论】:

  • 我相信这也是问题所在;我刚想到,但你已经为我写了:)
  • 这就是我尝试过的,除了 try..catch - 我将添加它。MSDN 是否试图说您只需要调用 BeginOutputReadLine 一次?还是需要在每行之后恢复?
  • (不在这个问题中,抱歉!)我需要记住互联网上的内容和没有的内容。
  • 听起来它只需要调用一次,并委托您的方法在输出一行时执行某些操作。每次输出新行时,它都会在您设置后继续调用该方法。
  • 好的,我现在又上线了,所以我会试试看。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
  • 2010-10-01
  • 2011-04-26
  • 1970-01-01
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多