C#获取运行的标准输入/输出/错误,而不是子进程



我的问题很简单:如何获得未启动进程的标准输出/输入/错误?假设我有一个程序(不是我的)XYZ,它整天运行,并将内容打印到stdout。我希望能够启动我的C#应用程序并开始读取XYZ的输出。然后关闭我的C#应用程序,2小时后重新启动它,继续读取输出(不一定是我停止的地方,但这将是一个好处)。

我知道如果XYZ是我的子进程,这是可以实现的

serverProcess = Process.Start(new ProcessStartInfo()
{
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
WorkingDirectory = WorkingDir,
Arguments = Args,
FileName = "XYZ",
UseShellExecute = false
});
serverProcess.OutputDataReceived += serverProcess_OutputDataReceived;
serverProcess.ErrorDataReceived += serverProcess_OutputDataReceived;
serverProcess.BeginOutputReadLine();
serverProcess.BeginErrorReadLine();

但事实并非如此,因为XYZ完全独立于我的应用程序,无论我对它做了什么,都需要继续运行。值得注意的是(如果有帮助的话)我可以自己启动XYZ(使用这些重定向参数)。只是我的生命周期需要完全独立于XYZ,并且我需要能够在重新启动后"重新连接"。

我看到了一些使用Get/SestdHandle的建议,但大多数都声称不起作用,而且我不太明白如何应用它们。

谢谢你的建议!

值得注意的是(如果有帮助的话)我可以自己启动XYZ(使用这些重定向参数)。只是我的生命周期需要完全独立于XYZ,并且我需要能够在重新启动后"重新连接"。

下面是我在评论中建议的一个简单实现(通过中间过程发布数据)。

基本上,样品由的三个主要部分组成

1.样本XYZ流程

在我们的例子中,它是一个每秒吐出一条来自XYZ的Hello消息的简单控制台应用程序。

class Program
{
static void Main(string[] args)
{
var count = 0;
while (true)
{
Console.WriteLine("Hello from XYZ "+count);
count++;
Thread.Sleep(1000);
}
}
}

2.中介流程

它应该启动XYZ并将其输出重定向到它自己,然后通过发布它。对于发布部分,我们在这里使用ZeroMQ库,可以很容易地从nuget获得。

class Program
{
private static Socket _pub;
static void Main(string[] args)
{
using (var context = new Context())
{
_pub = context.Socket(SocketType.PUB);
_pub.Bind("tcp://*:2550");
StartXyz();
Console.WriteLine("Press any key to close middle process...");
Console.ReadKey();
}
}
private static void StartXyz()
{
var serverProcess = Process.Start(new ProcessStartInfo
{
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
Arguments = string.Empty,
FileName = "XYZ.exe",
UseShellExecute = false
});
serverProcess.OutputDataReceived += serverProcess_OutputDataReceived;
serverProcess.ErrorDataReceived += serverProcess_OutputDataReceived;
serverProcess.BeginOutputReadLine();
serverProcess.BeginErrorReadLine();
}
private static void serverProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
_pub.Send(e.Data, Encoding.UTF8);
Console.WriteLine(e.Data + " pushed.");
}
}

3.消费者流程

最后,我们有了我们的流程,它使用来自XYZ的重定向数据。

class Program
{
static void Main(string[] args)
{
using (var context = new Context())
{
var sub = context.Socket(SocketType.SUB);
sub.Connect("tcp://localhost:2550");
sub.Subscribe(string.Empty, Encoding.UTF8);
while (true)
{
var data = sub.Recv(Encoding.UTF8);
Console.WriteLine(data);
}
}
}
} 

最新更新