Compare commits

...

2 commits

Author SHA1 Message Date
2dust
5732b84a7b Refactor KillProcess
Some checks are pending
release Linux / build (Release) (push) Waiting to run
release macOS / build (Release) (push) Waiting to run
release Windows / build (Release) (push) Waiting to run
2025-01-04 15:06:30 +08:00
2dust
c0d27504ac Refactor ProcessStart RebootAsAdmin 2025-01-03 20:56:51 +08:00
18 changed files with 184 additions and 185 deletions

View file

@ -0,0 +1,105 @@
using System.Diagnostics;
namespace ServiceLib.Common;
public static class ProcUtils
{
private static readonly string _tag = "ProcUtils";
public static void ProcessStart(string? fileName, string arguments = "")
{
ProcessStart(fileName, arguments, null);
}
public static int? ProcessStart(string? fileName, string arguments, string? dir)
{
if (fileName.IsNullOrEmpty())
{
return null;
}
try
{
if (fileName.Contains(' ')) fileName = fileName.AppendQuotes();
if (arguments.Contains(' ')) arguments = arguments.AppendQuotes();
Process process = new()
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = true,
FileName = fileName,
Arguments = arguments,
WorkingDirectory = dir
}
};
process.Start();
return process.Id;
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return null;
}
public static void RebootAsAdmin(bool blAdmin = true)
{
try
{
ProcessStartInfo startInfo = new()
{
UseShellExecute = true,
Arguments = Global.RebootAs,
WorkingDirectory = Utils.StartupPath(),
FileName = Utils.GetExePath().AppendQuotes(),
Verb = blAdmin ? "runas" : null,
};
Process.Start(startInfo);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
public static async Task ProcessKill(int pid)
{
try
{
await ProcessKill(Process.GetProcessById(pid), false);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
public static async Task ProcessKill(Process? proc, bool review)
{
if (proc is null)
{
return;
}
var fileName = review ? proc?.MainModule?.FileName : null;
var processName = review ? proc?.ProcessName : null;
try { proc?.Kill(true); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Kill(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Close(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Dispose(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
await Task.Delay(300);
if (review && fileName != null)
{
var proc2 = Process.GetProcessesByName(processName)
.FirstOrDefault(t => t.MainModule?.FileName == fileName);
if (proc2 != null)
{
Logging.SaveLog($"{_tag}, KillProcess not completing the job");
await ProcessKill(proc2, false);
proc2 = null;
}
}
}
}

View file

@ -591,26 +591,6 @@ namespace ServiceLib.Common
return Guid.TryParse(strSrc, out _);
}
public static void ProcessStart(string? fileName, string arguments = "")
{
try
{
if (fileName.IsNullOrEmpty())
{
return;
}
if (fileName.Contains(' ')) fileName = fileName.AppendQuotes();
if (arguments.Contains(' ')) arguments = arguments.AppendQuotes();
Process.Start(new ProcessStartInfo(fileName, arguments) { UseShellExecute = true });
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
public static Dictionary<string, string> GetSystemHosts()
{
var systemHosts = new Dictionary<string, string>();

View file

@ -55,7 +55,7 @@ namespace ServiceLib.Handler
{
if (node == null)
{
ShowMsg(false, ResUI.CheckServerSettings);
UpdateFunc(false, ResUI.CheckServerSettings);
return;
}
@ -63,13 +63,13 @@ namespace ServiceLib.Handler
var result = await CoreConfigHandler.GenerateClientConfig(node, fileName);
if (result.Success != true)
{
ShowMsg(true, result.Msg);
UpdateFunc(true, result.Msg);
return;
}
ShowMsg(true, $"{node.GetSummary()}");
ShowMsg(false, $"{Utils.GetRuntimeInfo()}");
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
UpdateFunc(true, $"{node.GetSummary()}");
UpdateFunc(false, $"{Utils.GetRuntimeInfo()}");
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
await CoreStop();
await Task.Delay(100);
await CoreStart(node);
@ -81,15 +81,23 @@ namespace ServiceLib.Handler
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard) ? ECoreType.sing_box : ECoreType.Xray;
var configPath = Utils.GetConfigPath(Global.CoreSpeedtestConfigFileName);
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);
ShowMsg(false, result.Msg);
UpdateFunc(false, result.Msg);
if (result.Success != true)
{
return -1;
}
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
ShowMsg(false, configPath);
return await CoreStartSpeedtest(configPath, coreType);
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
UpdateFunc(false, configPath);
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
var proc = await RunProcess(coreInfo, Global.CoreSpeedtestConfigFileName, true, false);
if (proc is null)
{
return -1;
}
return proc.Id;
}
public async Task CoreStop()
@ -98,13 +106,13 @@ namespace ServiceLib.Handler
{
if (_process != null)
{
await KillProcess(_process, true);
await ProcUtils.ProcessKill(_process, true);
_process = null;
}
if (_processPre != null)
{
await KillProcess(_processPre, true);
await ProcUtils.ProcessKill(_processPre, true);
_processPre = null;
}
@ -120,41 +128,8 @@ namespace ServiceLib.Handler
}
}
public async Task CoreStopPid(int pid)
{
try
{
await KillProcess(Process.GetProcessById(pid), false);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
#region Private
private string CoreFindExe(CoreInfo coreInfo)
{
var fileName = string.Empty;
foreach (var name in coreInfo.CoreExes)
{
var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
if (File.Exists(vName))
{
fileName = vName;
break;
}
}
if (Utils.IsNullOrEmpty(fileName))
{
var msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.CoreType.ToString()), string.Join(", ", coreInfo.CoreExes.ToArray()), coreInfo.Url);
Logging.SaveLog(msg);
ShowMsg(false, msg);
}
return fileName;
}
private async Task CoreStart(ProfileItem node)
{
var coreType = _config.RunningCoreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
@ -194,28 +169,7 @@ namespace ServiceLib.Handler
}
}
private async Task<int> CoreStartSpeedtest(string configPath, ECoreType coreType)
{
try
{
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
var proc = await RunProcess(coreInfo, Global.CoreSpeedtestConfigFileName, true, false);
if (proc is null)
{
return -1;
}
return proc.Id;
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
ShowMsg(false, ex.Message);
return -1;
}
}
private void ShowMsg(bool notify, string msg)
private void UpdateFunc(bool notify, string msg)
{
_updateFunc?.Invoke(notify, msg);
}
@ -233,11 +187,12 @@ namespace ServiceLib.Handler
#region Process
private async Task<Process?> RunProcess(CoreInfo coreInfo, string configPath, bool displayLog, bool mayNeedSudo)
private async Task<Process?> RunProcess(CoreInfo? coreInfo, string configPath, bool displayLog, bool mayNeedSudo)
{
var fileName = CoreFindExe(coreInfo);
var fileName = CoreInfoHandler.Instance.GetCoreExecFile(coreInfo, out var msg);
if (Utils.IsNullOrEmpty(fileName))
{
UpdateFunc(false, msg);
return null;
}
@ -272,12 +227,12 @@ namespace ServiceLib.Handler
proc.OutputDataReceived += (sender, e) =>
{
if (Utils.IsNullOrEmpty(e.Data)) return;
ShowMsg(false, e.Data + Environment.NewLine);
UpdateFunc(false, e.Data + Environment.NewLine);
};
proc.ErrorDataReceived += (sender, e) =>
{
if (Utils.IsNullOrEmpty(e.Data)) return;
ShowMsg(false, e.Data + Environment.NewLine);
UpdateFunc(false, e.Data + Environment.NewLine);
if (!startUpSuccessful)
{
@ -319,40 +274,11 @@ namespace ServiceLib.Handler
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
ShowMsg(true, ex.Message);
UpdateFunc(true, ex.Message);
return null;
}
}
private async Task KillProcess(Process? proc, bool review)
{
if (proc is null)
{
return;
}
var fileName = proc?.MainModule?.FileName;
var processName = proc?.ProcessName;
try { proc?.Kill(true); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Kill(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Close(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Dispose(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
await Task.Delay(500);
if (review)
{
var proc2 = Process.GetProcessesByName(processName)
.FirstOrDefault(t => t.MainModule?.FileName == fileName);
if (proc2 != null)
{
Logging.SaveLog($"{_tag}, KillProcess not completing the job");
await KillProcess(proc2, false);
proc2 = null;
}
}
}
#endregion Process
#region Linux

View file

@ -29,6 +29,27 @@
return _coreInfo ?? [];
}
public string GetCoreExecFile(CoreInfo? coreInfo, out string msg)
{
var fileName = string.Empty;
msg = string.Empty;
foreach (var name in coreInfo?.CoreExes)
{
var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
if (File.Exists(vName))
{
fileName = vName;
break;
}
}
if (fileName.IsNullOrEmpty())
{
msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.CoreType.ToString()), string.Join(", ", coreInfo.CoreExes.ToArray()), coreInfo.Url);
Logging.SaveLog(msg);
}
return fileName;
}
private void InitCoreInfo()
{
_coreInfo = [];

View file

@ -216,7 +216,7 @@ namespace ServiceLib.Services
{
if (pid > 0)
{
await CoreHandler.Instance.CoreStopPid(pid);
await ProcUtils.ProcessKill(pid);
}
await ProfileExHandler.Instance.SaveTo();
}
@ -278,7 +278,7 @@ namespace ServiceLib.Services
if (pid > 0)
{
await CoreHandler.Instance.CoreStopPid(pid);
await ProcUtils.ProcessKill(pid);
}
await ProfileExHandler.Instance.SaveTo();
}
@ -342,7 +342,7 @@ namespace ServiceLib.Services
if (pid > 0)
{
await CoreHandler.Instance.CoreStopPid(pid);
await ProcUtils.ProcessKill(pid);
}
await ProfileExHandler.Instance.SaveTo();
}

View file

@ -103,7 +103,7 @@ namespace ServiceLib.ViewModels
address = Utils.GetConfigPath(address);
if (File.Exists(address))
{
Utils.ProcessStart(address);
ProcUtils.ProcessStart(address);
}
else
{

View file

@ -130,11 +130,6 @@ namespace ServiceLib.ViewModels
DisplayOperationMsg(ResUI.LocalRestoreInvalidZipTips);
return;
}
if (!Utils.UpgradeAppExists(out _))
{
DisplayOperationMsg(ResUI.UpgradeAppNotExistTip);
return;
}
//backup first
var fileBackup = Utils.GetBackupPath(BackupFileName);
@ -150,12 +145,9 @@ namespace ServiceLib.ViewModels
if (Utils.IsWindows())
{
service?.RebootAsAdmin(false);
}
else
{
service?.Shutdown();
ProcUtils.RebootAsAdmin(false);
}
service?.Shutdown();
}
else
{

View file

@ -1,9 +1,7 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Diagnostics;
using System.Reactive;
using System.Reactive.Linq;
namespace ServiceLib.ViewModels
{
@ -319,20 +317,9 @@ namespace ServiceLib.ViewModels
return;
}
Process process = new()
var id = ProcUtils.ProcessStart(fileName, arg, Utils.StartupPath());
if (id > 0)
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = true,
FileName = fileName,
Arguments = arg.AppendQuotes(),
WorkingDirectory = Utils.StartupPath()
}
};
process.Start();
if (process.Id > 0)
{
await MyAppExitAsync(false);
await MyAppExitAsync(false);
}
}
@ -513,22 +500,10 @@ namespace ServiceLib.ViewModels
}
}
public async Task RebootAsAdmin(bool blAdmin = true)
public async Task RebootAsAdmin()
{
try
{
ProcessStartInfo startInfo = new()
{
UseShellExecute = true,
Arguments = Global.RebootAs,
WorkingDirectory = Utils.StartupPath(),
FileName = Utils.GetExePath().AppendQuotes(),
Verb = blAdmin ? "runas" : null,
};
Process.Start(startInfo);
await MyAppExitAsync(false);
}
catch { }
ProcUtils.RebootAsAdmin();
await MyAppExitAsync(false);
}
private async Task ClearServerStatistics()
@ -542,15 +517,15 @@ namespace ServiceLib.ViewModels
var path = Utils.StartupPath();
if (Utils.IsWindows())
{
Utils.ProcessStart(path);
ProcUtils.ProcessStart(path);
}
else if (Utils.IsLinux())
{
Utils.ProcessStart("nautilus", path);
ProcUtils.ProcessStart("nautilus", path);
}
else if (Utils.IsOSX())
{
Utils.ProcessStart("open", path);
ProcUtils.ProcessStart("open", path);
}
}

View file

@ -65,12 +65,12 @@ namespace v2rayN.Desktop.Views
private void linkDnsObjectDoc_Click(object? sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
ProcUtils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
}
private void linkDnsSingboxObjectDoc_Click(object? sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
}
}
}

View file

@ -330,12 +330,12 @@ namespace v2rayN.Desktop.Views
private void menuPromotion_Click(object? sender, RoutedEventArgs e)
{
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
ProcUtils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
}
private void menuSettingsSetUWP_Click(object? sender, RoutedEventArgs e)
{
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
}
public async Task ScanScreenTaskAsync()
@ -481,7 +481,7 @@ namespace v2rayN.Desktop.Views
{
if (sender is MenuItem item)
{
Utils.ProcessStart(item.Tag?.ToString());
ProcUtils.ProcessStart(item.Tag?.ToString());
}
}

View file

@ -95,7 +95,7 @@ namespace v2rayN.Desktop.Views
private void linkRuleobjectDoc_Click(object? sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://xtls.github.io/config/routing.html#ruleobject");
ProcUtils.ProcessStart("https://xtls.github.io/config/routing.html#ruleobject");
}
}
}

View file

@ -203,7 +203,7 @@ namespace v2rayN.Desktop.Views
private void linkCustomRulesetPath4Singbox(object? sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
ProcUtils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
}
}
}

View file

@ -117,12 +117,12 @@ namespace v2rayN.Desktop.Views
private void linkdomainStrategy_Click(object? sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://xtls.github.io/config/routing.html");
ProcUtils.ProcessStart("https://xtls.github.io/config/routing.html");
}
private void linkdomainStrategy4Singbox_Click(object? sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
}
private void btnCancel_Click(object? sender, RoutedEventArgs e)

View file

@ -66,12 +66,12 @@ namespace v2rayN.Views
private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
ProcUtils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
}
private void linkDnsSingboxObjectDoc_Click(object sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/dns/");
}
}
}

View file

@ -308,12 +308,12 @@ namespace v2rayN.Views
private void menuPromotion_Click(object sender, RoutedEventArgs e)
{
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
ProcUtils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
}
private void menuSettingsSetUWP_Click(object sender, RoutedEventArgs e)
{
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
}
private async Task ScanScreenTaskAsync()
@ -443,7 +443,7 @@ namespace v2rayN.Views
{
if (sender is MenuItem item)
{
Utils.ProcessStart(item.Tag.ToString());
ProcUtils.ProcessStart(item.Tag.ToString());
}
}

View file

@ -89,7 +89,7 @@ namespace v2rayN.Views
private void linkRuleobjectDoc_Click(object sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://xtls.github.io/config/routing.html#ruleobject");
ProcUtils.ProcessStart("https://xtls.github.io/config/routing.html#ruleobject");
}
}
}

View file

@ -197,7 +197,7 @@ namespace v2rayN.Views
private void linkCustomRulesetPath4Singbox(object sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
ProcUtils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
}
}
}

View file

@ -122,12 +122,12 @@ namespace v2rayN.Views
private void linkdomainStrategy_Click(object sender, System.Windows.RoutedEventArgs e)
{
Utils.ProcessStart("https://xtls.github.io/config/routing.html");
ProcUtils.ProcessStart("https://xtls.github.io/config/routing.html");
}
private void linkdomainStrategy4Singbox_Click(object sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
}
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)