Use job object to control child process

This commit is contained in:
Hongtao Zhang 2024-02-06 13:07:21 -06:00
parent 73f2c3b503
commit a524096fc2
2 changed files with 19 additions and 6 deletions

View file

@ -55,6 +55,7 @@
<ItemGroup>
<PackageReference Include="Droplex" Version="1.7.0" />
<PackageReference Include="FSharp.Core" Version="7.0.401" />
<PackageReference Include="Meziantou.Framework.Win32.Jobs" Version="3.2.1" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageReference Include="squirrel.windows" Version="1.5.2" NoWarn="NU1701" />
<PackageReference Include="StreamJsonRpc" Version="2.17.8" />

View file

@ -5,12 +5,24 @@ using System.IO.Pipelines;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin;
using Meziantou.Framework.Win32;
using Nerdbank.Streams;
namespace Flow.Launcher.Core.Plugin
{
internal abstract class ProcessStreamPluginV2 : JsonRPCPluginV2
{
private static JobObject _jobObject = new JobObject();
static ProcessStreamPluginV2()
{
_jobObject.SetLimits(new JobObjectLimits()
{
Flags = JobObjectLimitFlags.KillOnJobClose | JobObjectLimitFlags.DieOnUnhandledException
});
_jobObject.AssignProcess(Process.GetCurrentProcess());
}
public override string SupportedLanguage { get; set; }
protected sealed override IDuplexPipe ClientPipe { get; set; }
@ -30,22 +42,22 @@ namespace Flow.Launcher.Core.Plugin
ClientProcess = Process.Start(StartInfo);
ArgumentNullException.ThrowIfNull(ClientProcess);
SetupPipe(ClientProcess);
ErrorStream = ClientProcess.StandardError;
await base.InitAsync(context);
}
private void SetupPipe(Process process)
{
var (reader, writer) = (PipeReader.Create(process.StandardOutput.BaseStream),
PipeWriter.Create(process.StandardInput.BaseStream));
ClientPipe = new DuplexPipe(reader, writer);
}
public override async Task ReloadDataAsync()
{
var oldProcess = ClientProcess;
@ -57,8 +69,8 @@ namespace Flow.Launcher.Core.Plugin
await oldProcess.WaitForExitAsync();
oldProcess.Dispose();
}
public override async ValueTask DisposeAsync()
{
ClientProcess.Kill(true);