C#彻底关闭Windows系统代码,不用shutdown命令
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
以下是使用C#调用Windows API实现彻底关闭Windows系统的代码方案(不依赖 shutdown 命令),基于搜索结果整合优化: 方案一:直接调用 ExitWindowsEx API(需管理员权限) using System; using System.Runtime.InteropServices; public class SystemShutdown { // 导入Windows API函数 [DllImport("user32.dll", SetLastError = true)] private static extern bool ExitWindowsEx(uint uFlags, uint dwReason); // 常量定义 private const uint EWX_SHUTDOWN = 0x00000001; // 常规关机 private const uint EWX_POWEROFF = 0x00000008; // 关闭电源(若支持) private const uint EWX_FORCE = 0x00000004; // 强制终止进程 public static void Shutdown() { // 组合标志:强制关机并关闭电源 uint flags = EWX_SHUTDOWN | EWX_POWEROFF | EWX_FORCE; bool success = ExitWindowsEx(flags, 0);
if (!success) { int errorCode = Marshal.GetLastWin32Error(); throw new System.ComponentModel.Win32Exception(errorCode, "关机失败"); } } }
方案二:通过调整权限后调用API(更安全) 若上述方案因权限问题失败,需先获取系统权限(参考8): using System; using System.Runtime.InteropServices; public class AdvancedShutdown { [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct TokPriv1Luid { public int Count; public long Luid; public int Attr; } // 导入权限相关API [DllImport("advapi32.dll", SetLastError = true)] private static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); [DllImport("advapi32.dll", SetLastError = true)] private static extern bool LookupPrivilegeValueA(string host, string name, ref long pluid); [DllImport("advapi32.dll", SetLastError = true)] private static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); [DllImport("user32.dll", SetLastError = true)] private static extern bool ExitWindowsEx(int flg, int rea); // 权限常量 private const int SE_PRIVILEGE_ENABLED = 0x00000002; private const int TOKEN_QUERY = 0x00000008; private const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege"; public static void ForceShutdown() { IntPtr hToken = IntPtr.Zero; TokPriv1Luid tp = new TokPriv1Luid { Count = 1, Attr = SE_PRIVILEGE_ENABLED }; // 获取当前进程令牌并调整权限 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref hToken); LookupPrivilegeValueA(null, SE_SHUTDOWN_NAME, ref tp.Luid); AdjustTokenPrivileges(hToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); // 执行强制关机(组合多个标志) ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_POWEROFF, 0); } [DllImport("kernel32.dll")] private static extern IntPtr GetCurrentProcess(); } 关键说明 权限要求 必须以管理员身份运行程序,可通过以下任一方式实现: 在项目中添加 app.manifest 文件,设置: <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 运行时检查权限并提示用户(示例代码见1)。 参数选择 EWX_FORCE :强制终止未响应程序,但可能导致数据丢失。 EWX_POWEROFF :物理关闭电源(需硬件支持)8。 若需重启,可改用 EWX_REBOOT 标志822。 错误处理 通过 Marshal.GetLastWin32Error() 获取错误代码1。 常见错误: ERROR_SHUTDOWN_IN_PROGRESS (5)表示已有关机任务。 测试调用 class Program { static void Main() { try { AdvancedShutdown.ForceShutdown(); Console.WriteLine("关机指令已发送"); } catch (Exception ex) { Console.WriteLine($"错误:{ex.Message}"); } } } 注意事项 数据安全:强制关机可能导致未保存数据丢失,建议关键应用先触发保存逻辑1。 系统兼容性:代码适用于Windows系统,不同版本需测试API行为差异18。 替代方案:若需延迟关机,仍建议使用 shutdown.exe 命令(但用户要求禁用)2223。 该文章在 2025/5/14 1:05:12 编辑过 |
关键字查询
相关文章
正在查询... |