C# Shell - IO 重定向 [英] C# Shell - IO redirection

查看:16
本文介绍了C# Shell - IO 重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a replacement Windows shell in C#, and the feature I am currently implementing is having all IO inside the same shell window - ie, not opening cmd.exe in another window.

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

Right now, I have a partial solution to output. This is my code (where p is the running Process):

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

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

The process is set up with all the correct properties, such asUseShellExecute = False, RedirectStandard{Input, Output, Error} = True, and the event handlers are set up correctly, but it's inconsistent.

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

I have tried taking out the try/catch (which I know is extremely bad practice), and using a busy bool, which is set to false when the handler runs, but for some reason, I still get an InvalidOperationException on p.BeginOutputReadLine() - stating that there is already an async operation running.

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

Any help would be appreciated, even if it requires a completely different solution to the one above, rather than just fixing it.

谢谢.

编辑:这是启动进程的代码:

EDIT: Here is the code which starts the process:

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个字:

Also, I've realised that I'm not explaining what I mean by inconsistent. As they say, a picture is worth 2^3 words:

推荐答案

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

Methods prefixed with Begin typically run asynchronously. Is this what you want? Because it appears that the loop runs as fast as it can, calling more and more BeginOutputReadLine (because the call returns immediately, before it's done and the loop comes around for another iteration).

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

You could call ReadLine on the StandardOutput stream for a synchronous solution. Or:

    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):

Keep this in mind though (from MSDN):

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

When asynchronous read operations start, the event handler is called each time the associated Process writes a line of text to its StandardOutput stream.

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

You can cancel an asynchronous read operation by calling CancelOutputRead. The read operation can be canceled by the caller or by the event handler. After canceling, you can call BeginOutputReadLine again to resume asynchronous read operations.

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

That leads me to believe you should only call this method once and it will keep notifying you through callback when a line gets written.

这篇关于C# Shell - IO 重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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