这个问题不止一次被问过,但我在任何讨论中都没有找到满意的答案.
我正在启动一个命令行过程,它可以对STDOUT进行实时测量,大约每秒产生一个新结果.使用System.Diagnostics.Process.StandardOutput导致完全不可接受的延迟(超过20秒),因为STDOUT数据通过Process.StandardOutput StreamReader中的4k缓冲区工作,并且似乎没有任何方法可以解决这个问题.
调用Process.StandardOutput.BaseStream.Flush()不起作用.
我试过对Process.StandardOutput进行逐字节同步读取,但是我仍然比实际输出落后4k.
任何人都可以至少验证我有可能以某种方式克服我重定向STDOUT时遇到的所有缓冲问题,并且一旦它出现在shell窗口中就会立即收到我的应用程序中的数据吗?我可以继承Process类并更改StandardOutput流读取器的行为吗?我是否需要查看原始的WINAPI呼叫?
不知何故,这必须要完成,即使我最终编写非托管C++来启动任务并使用输出,并将其连接起来.任何帮助都非常感谢; 我的智慧结束了......
编辑:看来我需要的是可用于C/C++,Perl,Python和Java的"期望"库的.Net实现(这是迄今为止我发现的唯一库).有谁知道这样的野兽是否存在?
vbscript的要点是充当REPL或命令提示符/ bash环境,它简化为仅重印用户输入
因此,换句话说,cscript进程应保持活动状态,每次通过的用户输入应仅发送给该进程。
并且这也意味着应该为每次通过保留脚本的内部状态(一次=每次单击C#winform中的“发送”按钮,或者在vbscript的上下文中,一次=每次^ Z输入)。
例如,如果要修改vbscript以演示状态保持行为,则可以进行以下修改:
dim wsh,stmt,l...附加: dim passcnt : passcnt=1wsh.Echo("Enter lines of strings, press ctrl-z...,将最后一个右括号替换为& " (pass #" & passcnt & ")")wsh.Echo("End output")附加代码: passcnt = passcnt + 1运行vbscript控制台将显示通过次数在每次通过时递增。
- 只要上述条件仍然成立,就可以以任何方式修改C#winform。
- 尝试观察脚本的作用
cscript ask_SO.vbs,这应该使事情足够清楚
我认为这是我能够做到的最明确的目标。
我想使用System.Diagnostics.Process的stdout / stdin重定向将输入文本输入以下VBScript。
vbscript的作用在于,它允许用户向控制台输入多行字符串,并且当输入^ z字符时,脚本会将所有内容直接输出到控制台:
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.
Enter lines of …Run Code Online (Sandbox Code Playgroud) 我正在尝试为基于交互式控制台的应用程序编写包装器.为此,我使用C#和Process类.我正在尝试重定向stdin/ out/ err,但它不起作用.
示例代码:
ProcessStartInfo startInfo = new ProcessStartInfo("admin.exe");
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false;
Process process = Process.Start(startInfo);
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
process.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);
while (true)
{
process.StandardInput.Write("uptime" + Environment.NewLine);
process.StandardInput.Flush();
Thread.Sleep(1000);
}
Console.ReadKey();
Run Code Online (Sandbox Code Playgroud)
什么都没发生.但如果我开始admin.exe写uptime,输出就会打印出来.
互联网上的所有解决方案都使用ReadToEnd,但我不能使用它,因为我有一个动态的通信,我必须阅读stdout/ err写入stdin.
有人有想法吗?
我在链接的帖子上玩过贴子拉链.然后我尝试创建一个小的"概念证明"代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; …Run Code Online (Sandbox Code Playgroud)