using System.Diagnostics; namespace LanDesktopPLONDS.Installer.Services; /// /// 检测安装目录下是否有正在运行的进程。 /// 公开静态 API 供 ViewModel 后续调用。 /// public static class RunningProcessGuard { /// /// 检查指定安装路径下是否有正在运行的进程。 /// 如果找到进程,抛出 并列出进程名称。 /// /// 要检查的安装根目录。 public static void EnsureNoRunningProcesses(string installPath) { if (!OperatingSystem.IsWindows()) { return; } var running = FindRunningProcesses(installPath); if (running.Count == 0) { return; } var names = string.Join("、", running); throw new InvalidOperationException( $"以下进程正在运行,无法继续操作,请先关闭后再重试:{names}"); } /// /// 查找安装路径下正在运行的进程,返回进程名称列表。 /// 每个进程尝试获取 MainModule 路径时捕获 Access Denied 等异常。 /// public static List FindRunningProcesses(string installPath) { var result = new List(); if (!OperatingSystem.IsWindows()) { return result; } var normalizedInstall = Path.GetFullPath(installPath) .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); foreach (var process in Process.GetProcesses()) { try { var module = process.MainModule; if (module == null) { continue; } var modulePath = module.FileName; if (string.IsNullOrWhiteSpace(modulePath)) { continue; } var normalizedModule = Path.GetFullPath(modulePath); if (normalizedModule.StartsWith(normalizedInstall, StringComparison.OrdinalIgnoreCase)) { var processName = process.ProcessName; if (!string.IsNullOrWhiteSpace(processName) && !result.Contains(processName)) { result.Add(processName); } } } catch { // 访问被拒绝或其他异常,跳过此进程 } finally { process.Dispose(); } } return result; } }