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ī)(組合多個標(biāo)志)
ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_POWEROFF, 0);
}
[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentProcess();
}
關(guān)鍵說明
權(quán)限要求
必須以管理員身份運行程序,可通過以下任一方式實現(xiàn):
在項目中添加 app.manifest 文件,設(shè)置:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
運行時檢查權(quán)限并提示用戶(示例代碼見1)。
參數(shù)選擇
EWX_FORCE :強(qiáng)制終止未響應(yīng)程序,但可能導(dǎo)致數(shù)據(jù)丟失。
EWX_POWEROFF :物理關(guān)閉電源(需硬件支持)8。
若需重啟,可改用 EWX_REBOOT 標(biāo)志822。
錯誤處理
通過 Marshal.GetLastWin32Error() 獲取錯誤代碼1。
常見錯誤: ERROR_SHUTDOWN_IN_PROGRESS (5)表示已有關(guān)機(jī)任務(wù)。
測試調(diào)用
class Program
{
static void Main()
{
try
{
AdvancedShutdown.ForceShutdown();
Console.WriteLine("關(guān)機(jī)指令已發(fā)送");
}
catch (Exception ex)
{
Console.WriteLine($"錯誤:{ex.Message}");
}
}
}、?