我是一名有用的助手,可以为您翻译以下内容:
我在使用C# WPF应用程序启动控制台应用程序并重定向其stdin和stdout时遇到了一个有趣(读作:令人沮丧)的问题。
大部分工作都已经完成,但似乎当我开始重定向stdin时,就不能立即从stdout中获取一些数据。
我将通过一个示例来进行澄清。如果我不在STARTUPINFO结构中设置hStdInput,当我启动子进程时,我会收到以下内容:
MongoDB shell version: 2.2.0
connecting to: test
local:PRIMARY>
一旦我设置了hStdInput,我就得到了这个:
MongoDB shell version: 2.2.0
connecting to: test
我知道BackgroundWorker正在处理stdout,因为如果我向进程发送stdin中的内容,它会相应地做出反应。
use TestDB
switched to db TestDB
所以,这就是我创建这个过程的方式:
_processInfo = new ProcessInfo();
bool ok = false;
SECURITY_ATTRIBUTES sattr = new SECURITY_ATTRIBUTES();
sattr.bInheritHandle = 1;
unsafe
{
sattr.lpSecurityDescriptor = null;
}
sattr.nLength = Marshal.SizeOf(sattr);
IntPtr hWrite;
ok = CreatePipe(out _hReadStdOut, out hWrite, ref sattr, 0);
ok = SetHandleInformation(_hReadStdOut, HANDLE_FLAGS.INHERIT, 0);
IntPtr hRead;
ok = CreatePipe(out hRead, out _hWriteStdIn, ref sattr, 0);
ok = SetHandleInformation(_hWriteStdIn, HANDLE_FLAGS.INHERIT, 0);
var startInfo = new StartupInfo
{
dwFlags = 0x0001 | 0x0100,
wShowWindow = 0,
hStdOutput = hWrite,
hStdError = hWrite,
hStdInput = hRead // If this is IntPtr.Zero, I get everything from stdout
};
SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
pSec.nLength = Marshal.SizeOf(pSec);
SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES();
tSec.nLength = Marshal.SizeOf(tSec);
unsafe
{
ok = CreateProcess(
null,
pathToExeAndArgs,
ref pSec,
ref tSec,
true,
0,
IntPtr.Zero,
null,
ref startInfo,
out _processInfo);
}
我有一个BackgroundWorker在DoWork中处理stdout,读取管道的方式如下:
success = ReadFile(
_hReadStdOut,
bufPtr,
1024,
&read,
IntPtr.Zero);
我没有使用.Net Process类,因为它只有在控制台应用程序发送换行符后才能从stdout获取数据,所以即使在这种情况下我也无法得到提示符。
非常感谢您的任何帮助。
干杯。