C#徹底關(guān)閉Windows系統(tǒng)代碼,不用shutdown命令
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
?以下是使用C#調(diào)用Windows API實(shí)現(xiàn)徹底關(guān)閉Windows系統(tǒng)的代碼方案(不依賴 shutdown 命令),基于搜索結(jié)果整合優(yōu)化: 方案一:直接調(diào)用 ExitWindowsEx API(需管理員權(quán)限) using System; using System.Runtime.InteropServices; public class SystemShutdown { // 導(dǎo)入Windows API函數(shù) [DllImport("user32.dll", SetLastError = true)] private static extern bool ExitWindowsEx(uint uFlags, uint dwReason); // 常量定義 private const uint EWX_SHUTDOWN = 0x00000001; // 常規(guī)關(guān)機(jī) private const uint EWX_POWEROFF = 0x00000008; // 關(guān)閉電源(若支持) private const uint EWX_FORCE = 0x00000004; // 強(qiáng)制終止進(jìn)程 public static void Shutdown() { // 組合標(biāo)志:強(qiáng)制關(guān)機(jī)并關(guān)閉電源 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, "關(guān)機(jī)失敗"); } } }
方案二:通過(guò)調(diào)整權(quán)限后調(diào)用API(更安全) 若上述方案因權(quán)限問(wèn)題失敗,需先獲取系統(tǒng)權(quán)限(參考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; } // 導(dǎo)入權(quán)限相關(guān)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); // 權(quán)限常量 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 }; // 獲取當(dāng)前進(jìn)程令牌并調(diào)整權(quán)限 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); // 執(zhí)行強(qiáng)制關(guān)機(jī)(組合多個(gè)標(biāo)志) ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_POWEROFF, 0); } [DllImport("kernel32.dll")] private static extern IntPtr GetCurrentProcess(); } 關(guān)鍵說(shuō)明 權(quán)限要求 必須以管理員身份運(yùn)行程序,可通過(guò)以下任一方式實(shí)現(xiàn): 在項(xiàng)目中添加 app.manifest 文件,設(shè)置: <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 運(yùn)行時(shí)檢查權(quán)限并提示用戶(示例代碼見1)。 參數(shù)選擇 EWX_FORCE :強(qiáng)制終止未響應(yīng)程序,但可能導(dǎo)致數(shù)據(jù)丟失。 EWX_POWEROFF :物理關(guān)閉電源(需硬件支持)8。 若需重啟,可改用 EWX_REBOOT 標(biāo)志822。 錯(cuò)誤處理 通過(guò) Marshal.GetLastWin32Error() 獲取錯(cuò)誤代碼1。 常見錯(cuò)誤: ERROR_SHUTDOWN_IN_PROGRESS (5)表示已有關(guān)機(jī)任務(wù)。 測(cè)試調(diào)用 class Program { static void Main() { try { AdvancedShutdown.ForceShutdown(); Console.WriteLine("關(guān)機(jī)指令已發(fā)送"); } catch (Exception ex) { Console.WriteLine($"錯(cuò)誤:{ex.Message}"); } } } 注意事項(xiàng) 數(shù)據(jù)安全:強(qiáng)制關(guān)機(jī)可能導(dǎo)致未保存數(shù)據(jù)丟失,建議關(guān)鍵應(yīng)用先觸發(fā)保存邏輯1。 系統(tǒng)兼容性:代碼適用于Windows系統(tǒng),不同版本需測(cè)試API行為差異18。 替代方案:若需延遲關(guān)機(jī),仍建議使用 shutdown.exe 命令(但用戶要求禁用)2223。 該文章在 2025/5/14 1:05:12 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |