using System; using System.Diagnostics; using System.IO; using System.Management; using System.Security; using System.Security.Principal; using Microsoft.Win32; using PCL.Core.Logging; namespace PCL.Core.Utils.OS; public class ProcessInterop { /// /// 检查当前程序是否以管理员权限运行。 /// /// 如果当前用户具有管理员权限,则返回 true;否则返回 false。 public static bool IsAdmin() => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); /// /// 获取指定进程 ID 的命令行参数。 /// /// 进程 ID /// 命令行参数文本 public static string? GetCommandLine(int processId) { var query = $"SELECT CommandLine FROM Win32_Process WHERE ProcessId = {processId}"; using var searcher = new ManagementObjectSearcher(query); return searcher.Get().GetEnumerator().Current["CommandLine"].ToString(); } /// /// 从本地可执行文件启动新的进程。 /// /// 可执行文件路径 /// 程序参数 /// 指定是否以管理员身份启动该进程 /// 新的进程实例 public static Process? Start(string path, string? arguments = null, bool runAsAdmin = false) { var psi = new ProcessStartInfo(path); if (arguments is not null) psi.Arguments = arguments; if (runAsAdmin) { psi.UseShellExecute = true; psi.Verb = "runas"; } if (Directory.Exists(path)) psi.UseShellExecute = true; return Process.Start(psi); } /// /// 获取指定进程的可执行文件路径 /// /// 进程实例 /// 可执行文件路径,若无法获取则为 null public static string? GetExecutablePath(Process process) { try { var path = process.MainModule?.FileName; return (path is null) ? null : Path.GetFullPath(path); } catch { return null; } } /// /// 从本地可执行文件以管理员身份启动新的进程。 的套壳。 /// /// 可执行文件路径 /// 程序参数 /// 新的进程实例 public static Process? StartAsAdmin(string path, string? arguments = null) => Start(path, arguments, true); /// /// 结束指定进程。 /// /// 要结束的进程实例 /// 等待进程退出超时,以毫秒为单位,-1 表示无限制 /// 指定是否强制结束,若为 true 将通过带 /F 参数的 TASKKILL.EXE 结束进程 /// 进程返回值,若等待超时将返回 public static int Kill(Process process, int timeout = 3000, bool force = false) { if (force) Process.Start(new ProcessStartInfo("TASKKILL.EXE", $"/PID {process.Id} /F") { UseShellExecute = false }); else process.Kill(); if (timeout == -1) process.WaitForExit(); else if (timeout != 0) process.WaitForExit(timeout); return process.HasExited ? process.ExitCode : int.MinValue; } /// /// 将特定程序设置为使用高性能显卡启动。 /// /// 可执行文件路径。 /// 是否使用高性能显卡,默认为 true。 /// 当可执行文件路径无效时抛出 /// 当没有足够权限访问注册表时抛出 /// 当安全策略不允许访问注册表时抛出 /// 当注册表操作失败时抛出 public static void SetGpuPreference(string executable, bool wantHighPerformance = true) { // 参数验证 if (string.IsNullOrWhiteSpace(executable)) { throw new ArgumentException("可执行文件路径不能为空或仅包含空白字符", nameof(executable)); } // 验证文件路径格式 try { var fullPath = Path.GetFullPath(executable); if (!File.Exists(fullPath)) { LogWrapper.Warn("System", $"指定的可执行文件不存在: {executable}"); } } catch (Exception ex) when (ex is ArgumentException or NotSupportedException or PathTooLongException) { throw new ArgumentException($"无效的可执行文件路径: {executable}", nameof(executable), ex); } const string gpuPreferenceRegKey = @"Software\Microsoft\DirectX\UserGpuPreferences"; const string gpuPreferenceRegValueHigh = "GpuPreference=2;"; const string gpuPreferenceRegValueDefault = "GpuPreference=0;"; try { var isCurrentHighPerformance = _GetCurrentGpuPreference(executable, gpuPreferenceRegKey, gpuPreferenceRegValueHigh); LogWrapper.Info("System", $"当前程序 ({executable}) 的显卡设置为高性能: {isCurrentHighPerformance}"); // 如果当前设置已经是期望的设置,则无需修改 if (isCurrentHighPerformance == wantHighPerformance) { LogWrapper.Info("System", $"程序 ({executable}) 的显卡设置已经是期望的设置,无需修改"); return; } // 写入新设置 _SetGpuPreferenceValue(executable, wantHighPerformance, gpuPreferenceRegKey, gpuPreferenceRegValueHigh, gpuPreferenceRegValueDefault); } catch (UnauthorizedAccessException ex) { var errorMsg = "没有足够的权限访问注册表。请以管理员身份运行程序或检查用户权限设置。"; LogWrapper.Error(ex, "System", errorMsg); throw new UnauthorizedAccessException(errorMsg, ex); } catch (SecurityException ex) { var errorMsg = "安全策略不允许访问注册表。请联系系统管理员检查安全设置。"; LogWrapper.Error(ex, "System", errorMsg); throw new SecurityException(errorMsg, ex); } catch (Exception ex) { var errorMsg = $"设置 GPU 偏好时发生未预期的错误: {ex.Message}"; LogWrapper.Error(ex, "System", errorMsg); throw new InvalidOperationException(errorMsg, ex); } } /// /// 获取当前程序的GPU偏好设置 /// private static bool _GetCurrentGpuPreference(string executable, string regKey, string highPerfValue) { try { using var readOnlyKey = Registry.CurrentUser.OpenSubKey(regKey, false); if (readOnlyKey is null) { LogWrapper.Info("System", "GPU 偏好注册表键不存在,将在需要时创建"); return false; } var currentValue = readOnlyKey.GetValue(executable)?.ToString(); return string.Equals(currentValue, highPerfValue, StringComparison.OrdinalIgnoreCase); } catch (Exception ex) { LogWrapper.Warn(ex, "System", $"读取当前 GPU 偏好设置时出现错误: {ex.Message}"); return false; // 假设当前不是高性能模式 } } /// /// 设置GPU偏好值到注册表 /// private static bool _SetGpuPreferenceValue(string executable, bool wantHighPerformance, string regKey, string highPerfValue, string defaultValue) { RegistryKey? writeKey = null; try { // 尝试打开现有键进行写入 writeKey = Registry.CurrentUser.OpenSubKey(regKey, true); // 如果键不存在,创建它 if (writeKey is null) { LogWrapper.Info("System", "创建 GPU 偏好注册表键"); writeKey = Registry.CurrentUser.CreateSubKey(regKey); if (writeKey is null) { throw new InvalidOperationException($"无法创建注册表键: {regKey}"); } } var valueToSet = wantHighPerformance ? highPerfValue : defaultValue; writeKey.SetValue(executable, valueToSet, RegistryValueKind.String); LogWrapper.Info("System", $"成功设置程序 ({executable}) 的GPU偏好: {(wantHighPerformance ? "高性能" : "默认")}"); return true; } catch (UnauthorizedAccessException) { // 重新抛出,让上层处理 throw; } catch (SecurityException) { // 重新抛出,让上层处理 throw; } catch (Exception ex) { var errorMsg = $"写入注册表时发生错误: {ex.Message}"; LogWrapper.Error(ex, "System", errorMsg); throw new InvalidOperationException(errorMsg, ex); } finally { writeKey?.Dispose(); } } } public enum ProcessExitCode { /// /// Indicates that the process completed successfully. /// TaskDone = 0, /// /// Indicates a general failure of the process. /// Failed = 1, /// /// Indicates the process was canceled. /// Canceled = 2, /// /// Indicates the process failed due to insufficient permissions. /// AccessDenied = 5 }