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

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

问题描述

我写一个替代Windows外壳程序在C#中,和我目前正在实施的特点是具有相同shell窗口内的所有IO - 即在另一个窗口不开放的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.

现在,我要输出的部分解决方案。这是我的code(其中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 = RedirectStandard {输入,输出,错误} = ,以及事件处理程序设置正确,但它是不一致的。

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

我已经尝试取出的try / catch(我知道是非常不好的做法),并使用一个繁忙的布尔,它设置为false的处理程序运行的时候,但由于某些原因,我仍然可以在页码一个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.

任何帮助将是AP preciated,即使这需要上面的一个完全不同的解决方案之一,而不是仅仅将其固定。

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

感谢。

修改:这里是code的启动过程:

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 的话:

屏幕截图/

推荐答案

方法prefixed开始与一般异步运行。这是你想要什么?因为它看来,循环运行的速度,因为它可以,要求越来越多的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).

您可以打电话的ReadLine的StandardOutput流同步的解决方案。或者:

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

在异步读取操作   开始时,事件处理函数   每次相关流程   写一行文本到   StandardOutput流。

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#壳牌 - IO重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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