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 編輯過 |
關鍵字查詢
相關文章
正在查詢... |