C# Process.StandardInput 不起作用?试试这个方法
2024-08-04 15:37:35
C# Process.StandardInput 不起作用? 解決与外部程序交互的输入难题
你是否也曾遇到过这样的情况:兴致勃勃地用 C# 编写代码,试图向外部程序发送指令,却发现 Process.StandardInput
毫无反应,仿佛石沉大海?你可能尝试了各种方法,甚至翻遍了 Stack Overflow 上的解决方案,却依然无功而返。
这种情况并不少见,本文将带你深入了解 Process.StandardInput
的工作原理,并提供一些实用技巧,助你解决与外部程序交互时遇到的输入难题。为了更直观地说明问题,我们将以 Factorio 游戏服务器为例,为你展示如何解决 Process.StandardInput
失效的问题。
Process.StandardInput
:理应如此,却事与愿违
在 C# 中,我们通常使用 Process
类来启动和管理外部程序。为了向这些程序发送输入,我们可以设置 ProcessStartInfo
的 RedirectStandardInput
属性为 true
,然后使用 Process.StandardInput
属性获取一个 StreamWriter
对象,最后调用 StreamWriter.WriteLine()
方法向程序发送指令。
这一切看似完美无缺,然而现实往往更加复杂。由于外部程序的内部机制和处理逻辑各不相同,Process.StandardInput
并不总是能像我们预期的那样工作。
以 Factorio 游戏服务器为例,它在启动后会监听特定的端口,并通过该端口接收命令。如果你直接使用 Process.StandardInput.WriteLine()
发送命令,游戏服务器很可能无法识别,最终导致命令丢失。
PowerShell 的启示:另辟蹊径
在你的尝试中,你发现使用 PowerShell 代码却可以成功向 Factorio 服务器发送命令。这为我们提供了一个重要的线索:问题可能出在 C# 代码与游戏服务器的交互方式上。
让我们仔细分析一下你的 PowerShell 代码:
$p.StandardInput.WriteLine($cmd)
这段代码虽然简洁,但成功的关键在于它将命令发送到了游戏服务器监听的端口,而不是简单地写入 Process.StandardInput
。
C# 解决方案:建立 TCP 连接,直达目标
为了在 C# 中实现同样的效果,我们需要借助 TcpClient
类建立与游戏服务器的 TCP 连接,并将命令发送到正确的端口。
以下是修改后的 C# 代码:
using System;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace FactorioAutomatedAdmin
{
class Program
{
static void Main(string[] args)
{
var workingDir = @"E:\Program Files (x86)\Steam\steamapps\common\Factorio\bin\x64\";
var serverPort = 25565; // Factorio 默认服务器端口
var psi = new ProcessStartInfo
{
// ... 其他配置 ...
Arguments = @"--server-settings server-settings.json --start-server server.zip --port " + serverPort
};
var process = new Process
{
StartInfo = psi,
EnableRaisingEvents = true
};
process.Start();
// ... 处理输出 ...
// 建立 TCP 连接
using (var client = new TcpClient("localhost", serverPort))
using (var stream = client.GetStream())
{
while (true)
{
Console.Write("Command: ");
var command = Console.ReadLine() + "\n";
var commandBytes = Encoding.UTF8.GetBytes(command);
// 发送命令
stream.Write(commandBytes, 0, commandBytes.Length);
Thread.Sleep(1000);
}
}
}
}
}
代码解读:
- 首先,我们定义了游戏服务器的端口号
serverPort
,默认为 25565。 - 在启动游戏服务器时,我们将端口号添加到启动参数中,确保服务器监听正确的端口。
- 在主循环中,我们使用
TcpClient
连接到游戏服务器。 - 程序从控制台读取命令,并将其转换为字节数组。
- 最后,使用
stream.Write()
将命令发送到游戏服务器。
总结:知己知彼,方能百战不殆
通过使用 TcpClient
建立直接连接,我们成功解决了 Process.StandardInput
在与 Factorio 服务器交互时失效的问题。
需要注意的是,不同的外部程序可能有不同的通信协议和端口号。在解决类似问题时,我们需要仔细阅读相关文档,了解目标程序的通信机制,才能选择合适的解决方案。
希望本文能够帮助你更好地理解 Process.StandardInput
的工作原理,并为你解决与外部程序交互的难题提供新的思路。
常见问题解答:
1. 为什么我的 C# 代码无法向游戏服务器发送命令?
这很可能是因为你的代码没有将命令发送到游戏服务器监听的端口。请确保你的代码使用 TcpClient
连接到正确的端口,并将命令发送到该端口。
2. TcpClient
是什么?如何使用它?
TcpClient
是 .NET Framework 中的一个类,用于创建 TCP 连接。你可以使用它连接到远程服务器,并发送和接收数据。
3. 如何确定游戏服务器监听的端口号?
你可以查看游戏服务器的配置文件或文档,或者使用网络端口扫描工具来查找正在监听的端口。
4. 除了 TcpClient
之外,还有其他方法可以向外部程序发送命令吗?
是的,还有其他方法,例如使用命名管道或共享内存。但是,这些方法通常比使用 TcpClient
更复杂。
5. 如果我还有其他问题该怎么办?
你可以查阅相关文档,或者在 Stack Overflow 等技术论坛上寻求帮助。