将输入写入进程 - RedirectStandardInput 不起作用

问题描述 投票:0回答:1

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

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

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

我在这里做错了什么?

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# windows input process
1个回答
0
投票

我使用 python 和 node 遇到了同样的问题。显然,如果异星工厂是从控制台应用程序生成的,它会将其标准输入重新附加到控制台输入。令人困惑的是,当直接从控制台启动时不起作用。

无论如何,我能够通过使用 pythonw.exe 启动我的脚本来解决 python 中的问题,该脚本在用户模式下运行,而不是作为控制台程序运行。

如果您将 C# 应用程序构建为用户模式应用程序,我敢打赌这会解决该问题。

© www.soinside.com 2019 - 2024. All rights reserved.