c# - 将消息从一个 C# 控制台应用程序发送到另一个

标签 c# process console interop message

首先,我阅读了所有相关主题,他们给出了总体思路,但实现对我不起作用:
Send strings from one console application to another
How to send input to the console as if the user is typing?
Sending input/getting output from a console application (C#/WinForms)
我有一个控制台应用程序在后台执行一些操作,直到请求取消。典型的使用场景是:
1) 执行应用
2) 输入输入数据
3) 发出启动命令
4) 一段时间后,输入停止命令
5) 退出申请
子应用程序 Program.cs :

static void Main()
{
    Console.WriteLine("Enter input parameter : ");
    var inputParameter = Console.ReadLine();
    Console.WriteLine("Entered : " + inputParameter);

    var tokenSource = new CancellationTokenSource();
    var token = tokenSource.Token;
    Task.Factory.StartNew(() =>
        {
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Stopping actions");
                    return;
                }
                // Simulating some actions
                Console.Write("*");
            }
        }, token);
    if (Console.ReadKey().KeyChar == 'c')
    {
        tokenSource.Cancel();
        Console.WriteLine("Stop command");
    }
    Console.WriteLine("Finished");
    Console.ReadLine();
}

我正在寻找的是某种主机实用程序来控制此应用程序 - 生成多个实例并在每个实例上执行所需的用户操作。 主机应用程序 Program.cs :

static void Main()
{
    const string exe = "Child.exe";
    var exePath = System.IO.Path.GetFullPath(exe);
    var startInfo = new ProcessStartInfo(exePath)
    {
        RedirectStandardOutput = true,
        RedirectStandardInput = true,
        WindowStyle = ProcessWindowStyle.Hidden,
        WindowStyle = ProcessWindowStyle.Maximized,
        CreateNoWindow = true,
        UseShellExecute = false
    };

    var childProcess = new Process { StartInfo = startInfo };
    childProcess.OutputDataReceived += readProcess_OutputDataReceived;
    childProcess.Start();
    childProcess.BeginOutputReadLine();
    Console.WriteLine("Waiting 5s for child process to start...");
    Thread.Sleep(5000);

    Console.WriteLine("Enter input");
    var msg = Console.ReadLine();
    // Sending input parameter
    childProcess.StandardInput.WriteLine(msg);
    // Sending start command aka any key
    childProcess.StandardInput.Write("s");
    // Wait 5s while child application is working
    Thread.Sleep(5000);
    // Issue stop command
    childProcess.StandardInput.Write("c");
    // Wait for child application to stop
    Thread.Sleep(20000);
    childProcess.WaitForExit();
    Console.WriteLine("Batch finished");    
    Console.ReadLine();
}

当我运行此工具时,在第一次输入后它崩溃并出现“已停止工作”错误并提示将内存转储发送给 Microsoft。 VS 中的输出窗口显示没有异常。
猜猜这个问题发生在应用程序之间的某个地方,可能是因为输出流缓冲区溢出(子应用程序每秒写入大量星星,模仿可能巨大的真实输出),我还不知道如何修复它。我真的不需要将 child 的输出传递给主机(只向 child 发送开始-停止命令),但评论 RedirectStandardOutput 和 OutputDataReceived 并不能解决这个问题。任何想法如何使这项工作?

最佳答案

我建议使用 NamedPipeServerStreamNamedPipeClientStream,它们允许您打开一个流,该流将在给定机器上的进程之间进行通信。

首先,这将创建一个管道服务器流并等待有人连接到它:

    var stream = new NamedPipeServerStream(this.PipeName, PipeDirection.InOut);
    stream.WaitForConnection();
    return stream;

然后,这将连接到该流(来自您的其他进程),允许您在任一方向读取/写入:

    var stream = new NamedPipeClientStream(".", this.PipeName, PipeDirection.InOut);
    stream.Connect(100);
    return stream;

关于c# - 将消息从一个 C# 控制台应用程序发送到另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18742413/

相关文章:

c# - 如何将 DataSource 设置为 DropDownList?

jupyter-notebook - IPython REPL 任何地方 : how to share application context with IPython console for future interaction?

c# - 在 SQL 查询中传递 DECLARE 参数

c - 测量n个进程的时间

c - 观察进程状态转换

c# - 以管理员身份运行 cmd 和命令?

c - 使控制台中字符的宽度和高度以像素为单位相等 (C)

javascript - 脚本加载后如何运行函数

c# - 保存到数据库时出现 InvalidOperationException

c# - 如何读取给定文件夹中的所有文件?