From 4df487ef58ac3958117c94e8f54eaf80db7df9b8 Mon Sep 17 00:00:00 2001 From: Elivo Date: Fri, 18 Jul 2025 16:09:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20CatchException=EF=BC=8C?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E6=8D=95=E8=8E=B7=E5=BC=82=E5=B8=B8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Apewer.Windows/WindowsUtility.cs | 54 ++++++++++++++++++++++++++++++++ Apewer/Apewer.csproj | 3 ++ Apewer/RuntimeUtility.cs | 21 ++++++++++--- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/Apewer.Windows/WindowsUtility.cs b/Apewer.Windows/WindowsUtility.cs index b0bf8bf..ea721a9 100644 --- a/Apewer.Windows/WindowsUtility.cs +++ b/Apewer.Windows/WindowsUtility.cs @@ -163,6 +163,49 @@ namespace Apewer catch { return false; } } + /// 获取同名进程。 + public static Process[] PreviousProcess() + { + var current = Process.GetCurrentProcess(); + + var result = new List(); + var all = Process.GetProcesses(); + foreach (var process in all) + { + if (process.Id == current.Id) continue; + if (process.ProcessName != current.ProcessName) continue; + result.Add(process); + } + return result.ToArray(); + } + + /// 结束同名进程。 + /// 在强制结束进程前执行的方法。 + /// + /// + /// + public static void KillPreviousProcess(Action before = null) + { + var current = Process.GetCurrentProcess(); + var processes = Process.GetProcesses(); + foreach (var process in processes) + { + if (process.Id == current.Id) continue; + if (process.ProcessName != current.ProcessName) continue; + + before?.Invoke(process); + try + { + if (process.HasExited) continue; + process.Kill(); + } + catch + { + if (!process.HasExited) throw; + } + } + } + /// 查询指定的进程 ID 是否存在。 /// 进程 ID。 public static bool ProcessIsAlive(int pid) @@ -384,6 +427,17 @@ namespace Apewer throw new SystemException($"向内存地址写入数据失败。"); } + /// 捕获异常。 + /// 此方法内会自动调用 方法,无需重复调用。 + public static void CatchException(Action callback) + { + RuntimeUtility.CatchException(callback); +#if !NETFRAMEWORK + System.Windows.Forms.Application.SetUnhandledExceptionMode(System.Windows.Forms.UnhandledExceptionMode.CatchException); + System.Windows.Forms.Application.ThreadException += (s, e) => callback(e.Exception); +#endif + } + #endregion #region 控制台。 diff --git a/Apewer/Apewer.csproj b/Apewer/Apewer.csproj index 4075928..9c13265 100644 --- a/Apewer/Apewer.csproj +++ b/Apewer/Apewer.csproj @@ -23,6 +23,7 @@ + @@ -31,6 +32,7 @@ + @@ -39,6 +41,7 @@ + diff --git a/Apewer/RuntimeUtility.cs b/Apewer/RuntimeUtility.cs index da07d3d..48e39df 100644 --- a/Apewer/RuntimeUtility.cs +++ b/Apewer/RuntimeUtility.cs @@ -1,7 +1,5 @@ -using Apewer.Internals; -using Apewer.Models; +using Apewer.Models; using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -9,7 +7,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Threading; -using static System.Net.Mime.MediaTypeNames; namespace Apewer { @@ -906,6 +903,22 @@ namespace Apewer get { return Process.GetCurrentProcess().MainModule.FileName; } } + /// 捕获异常。 + /// + public static void CatchException(Action callback) + { + if (callback == null) throw new ArgumentNullException(nameof(callback)); + + AppDomain.CurrentDomain.UnhandledException += (s, e) => callback(e.ExceptionObject as Exception); +#if !NET20 + System.Threading.Tasks.TaskScheduler.UnobservedTaskException += (s, e) => callback(e.Exception); +#endif +#if NETFRAMEWORK + System.Windows.Forms.Application.SetUnhandledExceptionMode(System.Windows.Forms.UnhandledExceptionMode.CatchException); + System.Windows.Forms.Application.ThreadException += (s, e) => callback(e.Exception); +#endif + } + #endregion #region Evaluate