Это сводило меня с ума на весь день. Я больше не уверен, делаю ли я здесь что-то глупое, но все стандартные решения и обходные пути, которые я попробовал, безрезультатны. Я прошу прощения за вопрос, похожий на многие уже существующие, но все мои запросы встречаются с большим количеством решений того же типа, как показано ниже, фрагментов кода, которые, к сожалению, не имеют никакого эффекта в моем конкретном случае c. Может быть, это что-то особенное в самом процессе.
Цель очень проста: у меня есть внешний процесс (.exe), на который я хочу программно отправлять ввод.
Перенаправление вывода происходит без каких-либо проблем: программа запускается, и я получаю ожидаемый результат на экране. Если я сфокусируюсь на процессе и вручную введу данные (введите команду и нажмите клавишу ввода), программа также отреагирует так, как ожидалось: она выведет команду обратно в указанном формате c. Тем не менее, автоматические «Test» заявления ниже не возвращаются по какой-то причине. Они также не отображаются в самом приложении, поэтому я уверен, что программа вообще ничего не получает.
Что я здесь не так делаю?
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#, я бы хотел услышать его: это даст мне больше возможностей для работы.