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}");
}
}
}、?