using CliWrap; using CliWrap.Buffered; namespace ServiceLib.Manager; public class CoreAdminManager { private static readonly Lazy _instance = new(() => new()); public static CoreAdminManager Instance => _instance.Value; private Config _config; private Func? _updateFunc; private int _linuxSudoPid = -1; private const string _tag = "CoreAdminHandler"; public async Task Init(Config config, Func updateFunc) { if (_config != null) { return; } _config = config; _updateFunc = updateFunc; await Task.CompletedTask; } private async Task UpdateFunc(bool notify, string msg) { await _updateFunc?.Invoke(notify, msg); } public async Task RunProcessAsLinuxSudo(string fileName, CoreInfo coreInfo, string configPath) { StringBuilder sb = new(); sb.AppendLine("#!/bin/bash"); var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}"; sb.AppendLine($"exec sudo -S -- {cmdLine}"); var shFilePath = await FileUtils.CreateLinuxShellFile("run_as_sudo.sh", sb.ToString(), true); var procService = new ProcessService( fileName: shFilePath, arguments: "", workingDirectory: Utils.GetBinConfigPath(), displayLog: true, redirectInput: true, environmentVars: null, updateFunc: _updateFunc ); await procService.StartAsync(AppManager.Instance.LinuxSudoPwd); if (procService is null or { HasExited: true }) { throw new Exception(ResUI.FailedToRunCore); } _linuxSudoPid = procService.Id; return procService; } public async Task KillProcessAsLinuxSudo() { if (_linuxSudoPid < 0) { return; } try { var shellFileName = Utils.IsOSX() ? Global.KillAsSudoOSXShellFileName : Global.KillAsSudoLinuxShellFileName; var shFilePath = await FileUtils.CreateLinuxShellFile("kill_as_sudo.sh", EmbedUtils.GetEmbedText(shellFileName), true); if (shFilePath.Contains(' ')) { shFilePath = shFilePath.AppendQuotes(); } var arg = new List() { "-c", $"sudo -S {shFilePath} {_linuxSudoPid}" }; var result = await Cli.Wrap(Global.LinuxBash) .WithArguments(arg) .WithStandardInputPipe(PipeSource.FromString(AppManager.Instance.LinuxSudoPwd)) .ExecuteBufferedAsync(); await UpdateFunc(false, result.StandardOutput.ToString()); } catch (Exception ex) { Logging.SaveLog(_tag, ex); } _linuxSudoPid = -1; } }