首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 實現關機、重開機、登出:ExitWindowsEx API 完整指南

     編輯:Delphi

前言

系統管理工具、安裝程式、排程軟體常需程式化控制 Windows 關機/重開機/登出。核心 API 為 ExitWindowsEx。

API 宣告與常數

function ExitWindowsEx(uFlags: UINT; dwReserved: DWORD): BOOL; stdcall; external 'user32.dll';

const
  EWX_LOGOFF   = 0;  { 登出 }
  EWX_SHUTDOWN = 1;  { 關機 }
  EWX_REBOOT   = 2;  { 重開機 }
  EWX_FORCE    = 4;  { 強制關閉應用程式(不儲存資料) }
  EWX_POWEROFF = 8;  { 關機並切斷電源 (ATX) }
  EWX_FORCEIFHUNG = 10; { 僅強制關閉無回應程式 }

基本用法

var
  How: UINT;
begin
  How := EWX_SHUTDOWN;  { 或 EWX_REBOOT, EWX_LOGOFF }
  if not ExitWindowsEx(How, 0) then
    ShowMessage('操作失敗,錯誤碼: ' + IntToStr(GetLastError));
end;

進階:關機前權限調整 (SeShutdownPrivilege)

在 NT 核心系統 (2000/XP/Vista/7/10/11) 上,呼叫進程需擁有 SE_SHUTDOWN_NAME 特權,否則 ExitWindowsEx 會失敗 (ERROR_PRIVILEGE_NOT_HELD = 1314)。

uses WinSvc;  { 或手動宣告 OpenProcessToken, LookupPrivilegeValue, AdjustTokenPrivileges }

function EnableShutdownPrivilege: Boolean;
var
  hToken: THandle;
  tp: TTokenPrivileges;
begin
  Result := False;
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
  try
    if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tp.Privileges[0].Luid) then
    begin
      tp.PrivilegeCount := 1;
      tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
      Result := AdjustTokenPrivileges(hToken, False, tp, 0, nil, DWORD(0));
    end;
  finally
    CloseHandle(hToken);
  end;
end;

procedure TForm1.ShutdownSystem;
begin
  if EnableShutdownPrivilege then
  begin
    if not ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCEIFHUNG, 0) then
      ShowMessage('關機失敗: ' + SysErrorMessage(GetLastError));
  end
  else
    ShowMessage('無法取得關機特權,請以管理員身分執行。');
end;

現代替代方案:InitiateSystemShutdownEx

支援遠端關機、倒數計時、自訂訊息、強制應用程式關閉:

function InitiateSystemShutdownEx(
  lpMachineName: PWideChar; lpMessage: PWideChar;
  dwTimeout: DWORD; bForceAppsClosed: BOOL; bRebootAfterShutdown: BOOL;
  dwReason: DWORD): BOOL; stdcall; external 'advapi32.dll';

{ 範例:60 秒後重開機,顯示訊息 }
InitiateSystemShutdownEx(nil, '系統將在 60 秒後重新啟動進行更新', 60, True, True,
  SHTDN_REASON_MAJOR_OPERATINGSYSTEM or SHTDN_REASON_MINOR_INSTALLATION or SHTDN_REASON_FLAG_PLANNED);

結語

掌握 ExitWindowsEx 基本用法與 SE_SHUTDOWN_NAME 特權調整,是開發系統級工具的必備技能。新專案建議改用 InitiateSystemShutdownEx 獲得更豐富的控制選項。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved