首页 > 解决方案 > 将输入写入进程 - RedirectStandardInput 不起作用

问题描述

这让我一整天都发疯了。我不确定我是否在这里做一些愚蠢的事情,但是我尝试过的所有标准解决方案和解决方法都没有任何积极的结果。我很抱歉问了一个与许多已经存在的问题类似的问题,但是我的所有查询都受到了更多相同类型的解决方案的欢迎,如下所示,遗憾的是,这些代码对我的具体情况没有任何影响。也许这是过程本身的特殊之处。

目标非常简单:我有一个外部进程 (.exe),我想以编程方式向其发送输入。

重定向输出没有任何问题:程序启动,我在屏幕上得到预期的输出。如果我关注该过程并手动输入(键入命令并按回车键),程序也会按预期响应:它以特定格式回显命令。然而,由于某种原因,下面的自动“测试”语句没有返回。它们也不会出现在应用程序本身中,所以我确信该程序根本没有收到任何东西。

我在这里做错了什么?

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;

namespace Factorio_AutomatedAdmin
{
    class Program
    {
        static void Main(string[] args)
        {
            var workingDir = @"E:\Program Files (x86)\Steam\steamapps\common\Factorio\bin\x64\";

            var psi = new ProcessStartInfo
            {
                UseShellExecute = false,
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                RedirectStandardInput = true,
                StandardErrorEncoding = Encoding.UTF8,
                StandardOutputEncoding = Encoding.UTF8,
                WindowStyle = ProcessWindowStyle.Hidden,
                CreateNoWindow = true,
                WorkingDirectory = workingDir,
                FileName = $"{workingDir}factorio",
                Arguments = @"--server-settings server-settings.json --start-server server.zip"""
            };

            var process = new Process
            {
                StartInfo = psi,
                EnableRaisingEvents = true
            };

            process.Start();

            process.OutputDataReceived += (o, e) =>
            {
                var err = "";
                if (e.Data == null) err = e.Data;
                else Console.WriteLine(e.Data);
            };
            process.BeginOutputReadLine();

            process.ErrorDataReceived += (o, e) =>
            {
                var err = "";
                if (e.Data == null) err = e.Data;
                else Console.WriteLine(e.Data);
            };

            process.BeginErrorReadLine();

            StreamWriter sw = process.StandardInput;

            while (true)
            {
                sw.WriteLine("Test");
                Thread.Sleep(1000);
            }
        }
    }
}

提前感谢您的帮助!

更新:仍然无法让它在 C# 中工作,但 PowerShell 的以下代码确实具有预期的效果:

$dir = "E:\Program Files (x86)\Steam\steamapps\common\Factorio\bin\x64\"
$serverPath = $dir + "factorio.exe"
$spectator = "Tybs"

Set-Location -Path $dir

$psi = New-Object System.Diagnostics.ProcessStartInfo;
$psi.FileName = $serverPath; #process file
$psi.UseShellExecute = $false; #start the process from it's own executable file
$psi.RedirectStandardInput = $true; #enable the process to read from standard input
$psi.RedirectStandardOutput = $true; #enable the process to read from standard output
$psi.RedirectStandardError = $true;
$psi.Arguments = '--server-settings "E:\Program Files (x86)\Steam\steamapps\common\Factorio\bin\x64\server-settings.json" --start-server tybsania.zip'

$p = New-Object System.Diagnostics.Process
$p.StartInfo = $psi

# Register Object Events for stdin\stdout reading
$OutEvent = Register-ObjectEvent -Action {
    $data = $Event.SourceEventArgs.Data
    Write-Host $data
    return $data
} -InputObject $p -EventName OutputDataReceived -MessageData $players

$ErrEvent = Register-ObjectEvent -Action {
    Write-Host $Event.SourceEventArgs.Data
} -InputObject $p -EventName ErrorDataReceived

[void]$p.Start()
$p.BeginOutputReadLine();
$p.BeginErrorReadLine();

while($true)
{
    $cmd = Read-Host "Command"
    $p.StandardInput.WriteLine($cmd)
}

至少这是一种解决方法。不过,如果有人对 C# 有答案,我很想听听:这会给我更多的选择。

标签: c#windowsinputprocess

解决方案


推荐阅读