我正在尝试为基于交互式控制台的应用程序编写包装器。为此,我使用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();
什么都没发生。但如果我开始admin.exe
并写uptime
,则会打印输出。
互联网上的所有解决方案都使用ReadToEnd
,但我无法使用此功能,因为我有动态通信,我必须阅读stdout
/ err
并写入{{ 1}}。
有人有想法吗?
我在链接线程上使用发布的zip进行了播放。然后我尝试创建一个小的“概念验证”代码:
stdin
完美无缺: - )
但是使用using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace ConsoleApplication3
{
class Program
{
private static void Read(StreamReader reader)
{
new Thread(() =>
{
while (true)
{
int current;
while ((current = reader.Read()) >= 0)
Console.Write((char)current);
}
}).Start();
}
static void Main(string[] args)
{
ProcessStartInfo startInfo = new ProcessStartInfo(@"cmd.exe");
startInfo.CreateNoWindow = true;
startInfo.ErrorDialog = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
Read(process.StandardOutput);
Read(process.StandardError);
while (true)
process.StandardInput.WriteLine(Console.ReadLine());
}
}
}
它不起作用? admin.exe
不使用任何棘手的输入法,也不需要输入密码。
我知道admin.exe
是用c编写的,并在linux上用mingw编译。所以我创建了一个小型虚拟工具:
admin.exe
此工具仅回显输入的文本/行。我用#include <stdio.h>
int main() {
int readed;
while ((readed = fgetc(stdin)) >= 0)
fputc((char)readed, stdout);
}
编译它并将其复制到我的Windows机器上。在那里,我使用这篇文章顶部的程序与i586-mingw32msvc-gcc
进行通信。它不起作用。没有显示回声。但为什么呢?
我也使用Microsoft C ++编译器编译了虚拟代码,效果相同。
我正在努力尝试。我尝试创建一个c-Tool,它和我的c#工具一样。我使用dummy.exe
,但效果是,输出显示在流程结束时。嗯,不好。
我为windows找到了这个替代命令shell:
https://stackoverflow.com/questions/440269/whats-a-good-alternative-windows-console
http://sourceforge.net/projects/console/
似乎有效。它实时获取stdout / err,可以重定向标准输入和_popen
工作。它是开源的。也许我会在C ++ - Code中找到解决方案。
我在C ++方面表现不佳,所以很难,但我会尝试一下。可能我必须用C / C ++编写一个“清晰”的重定向包装器并在C#中使用它。
如果有人有想法请说出来,因为另一种方式可能非常难(对我来说^^): - )
感谢。
最好的问候
嗯,我认为这是因为子进程(admin.exe
)使用了几个线程...
但是如何解决呢?
答案 0 :(得分:1)
问题可能是,因为你正在使用Readline
,其中数据是从admin.exe
应用程序输出的,是顺序而不是新行...,尝试使用相反,Read
,并从中构建所需的字符串..
此外,您不必使用Environment.NewLine
来编写字符串后跟新行,而是使用WriteLine
,所以:
process.StandardInput.WriteLine("uptime");