Flow.Launcher/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs
2023-11-26 09:33:34 -06:00

70 lines
2.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin;
using Nerdbank.Streams;
namespace Flow.Launcher.Core.Plugin
{
internal abstract class ProcessStreamPluginV2 : JsonRPCPluginV2
{
public override string SupportedLanguage { get; set; }
protected sealed override IDuplexPipe ClientPipe { get; set; }
protected abstract ProcessStartInfo StartInfo { get; set; }
protected Process ClientProcess { get; set; }
public override async Task InitAsync(PluginInitContext context)
{
StartInfo.EnvironmentVariables["FLOW_VERSION"] = Constant.Version;
StartInfo.EnvironmentVariables["FLOW_PROGRAM_DIRECTORY"] = Constant.ProgramDirectory;
StartInfo.EnvironmentVariables["FLOW_APPLICATION_DIRECTORY"] = Constant.ApplicationDirectory;
StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
StartInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
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;
ClientProcess = Process.Start(StartInfo);
ArgumentNullException.ThrowIfNull(ClientProcess);
SetupPipe(ClientProcess);
await base.ReloadDataAsync();
oldProcess.Kill(true);
await oldProcess.WaitForExitAsync();
oldProcess.Dispose();
}
public override async ValueTask DisposeAsync()
{
ClientProcess.Kill(true);
await ClientProcess.WaitForExitAsync();
ClientProcess.Dispose();
await base.DisposeAsync();
}
}
}