我正在尝试(最终)为长时间运行的 .exe 应用程序(例如加密节点或游戏服务器)编写 C# 服务包装器。到目前为止,我已经编写了一个输出 .exe 输出的小型 PowerShell 主机(当前到控制台,最终它会转到其他地方)和一个小型示例应用程序,它每秒输出一次时间,并位于 Console.ReadLine()
处寻找“停止”停止执行。目前我能够托管示例应用程序并正确地将输出定向(到控制台),但我需要知道如何在调用 PowerShell.Invoke()
后添加命令。
像游戏服务器这样的程序通常有可用的命令,比如“保存”或“退出”来控制服务器。程序在托管的 PowerShell 会话中运行后,我想添加一个“停止”命令来停止示例应用程序,但我不知道如何。
我的目标是 .NET 5.0
并使用 Microsoft.PowerShell.SDK
软件包
下面是我的代码
请注意,第 15 行 Console.WriteLine("Started");
将执行,但以下语句(包括 Console.WriteLine("Attempting stop");
和之后)将不会执行,或者至少不会进入控制台。
using System;
using System.Management.Automation;
namespace ServiceWrapper
{
class Program
{
static void Main(string[] args)
{
// Create the hosting session
var ps = PowerShell.Create();
ps.AddScript("& C:\\Code\\SimpleServiceWrapper\\TestApplication\\SampleApp.exe");
// Hook the output
var output = new PSDataCollection<PSObject>();
output.DataAdded += new EventHandler<DataAddedEventArgs>(InformationEventHandler);
ps.Invoke(null, output);
Console.WriteLine("Started");
// This code is not run
Console.WriteLine("Attempting stop");
ps.AddStatement().AddCommand("stop");
ps.Invoke();
}
// Write output live to the console
static void InformationEventHandler(object sender, DataAddedEventArgs e)
{
var myp = (PSDataCollection<PSObject>)sender;
var results = myp.ReadAll();
foreach (PSObject result in results)
{
Console.WriteLine(result.ToString());
}
}
}
}
这个小应用程序的目标是模拟一个长时间运行的程序(如游戏服务器)并需要一些输入(如“停止”)才能正确退出程序。这主要是为了完整性
using System;
using System.Timers;
namespace SampleApp
{
class SampleApp
{
static void Main(string[] args)
{
// Setup a simple 1 second timer
var timer = new Timer(1000) { AutoReset = true };
timer.Elapsed += TimerElapsedEventHandler;
timer.Start();
// loop until told to stop
var loop = true;
while (loop)
{
var stop = Console.ReadLine();
if (stop.ToLower() == "stop")
{
loop = false;
Console.WriteLine("Stopping");
}
}
}
// Every 1 second, write the time
private static void TimerElapsedEventHandler(object sender, ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now);
}
}
}
由于示例程序需要读取“停止”才能正确停止,在托管 PowerShell 对象上已调用 Invoke()
后,如何以编程方式发送该内容?本质上是复制坐在控制台的用户,但不是用户,而是程序。