可以使用 Windows API 中的 ExitWindowsEx 函数来实现定时关机。

具体步骤如下:

  1. 定义一个 TTimer 组件,设置其时间间隔为一分钟。在每次 Timer 的 OnTimer 事件中,将剩余时间减 1 秒并更新界面上的倒计时显示。

  2. 在界面上添加一个按钮,点击按钮时,先调用 Windows API 中的 OpenProcessToken 函数获取当前进程的令牌(token),然后调用 AdjustTokenPrivileges 函数启用关机权限。

  3. 在需要定时关机的时候,调用 ExitWindowsEx 函数,设置参数为 EWX_SHUTDOWN 或 EWX_POWEROFF。其中,EWX_SHUTDOWN 表示正常关机,EWX_POWEROFF 表示强制关机。

完整代码示例:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    Label1: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FLeftTime: Integer; // 剩余时间(秒)
    procedure ShutDown(Flag: Cardinal);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// 获取当前进程的令牌
function OpenProcessToken(ProcessHandle: THandle; DesiredAccess: DWORD;
  var TokenHandle: THandle): BOOL; stdcall; external advapi32 name 'OpenProcessToken';

// 启用关机权限
function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL;
  const NewState: TTokenPrivileges; BufferLength: DWORD; PreviousState: PTokenPrivileges;
  var ReturnLength: DWORD): BOOL; stdcall; external advapi32 name 'AdjustTokenPrivileges';

// 关机
function ExitWindowsEx(uFlags: UINT; dwReason: DWORD): BOOL; stdcall; external user32 name 'ExitWindowsEx';

procedure TForm1.Button1Click(Sender: TObject);
var
  hToken: THandle;
  tkp: TTokenPrivileges;
begin
  // 启用关机权限
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
  begin
    tkp.PrivilegeCount := 1;
    LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid);
    tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, False, tkp, 0, nil, nil);
    CloseHandle(hToken);
  end;

  // 定时关机
  FLeftTime := 60; // 60秒后关机
  Label1.Caption := IntToStr(FLeftTime) + '秒后关机...';
  Timer1.Enabled := True;
end;

procedure TForm1.ShutDown(Flag: Cardinal);
begin
  ExitWindowsEx(Flag, 0);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Dec(FLeftTime);
  Label1.Caption := IntToStr(FLeftTime) + '秒后关机...';
  if FLeftTime <= 0 then
  begin
    Timer1.Enabled := False;
    ShutDown(EWX_SHUTDOWN); // 正常关机
    //ShutDown(EWX_POWEROFF); // 强制关机
  end;
end;

end. 
Delphi 实现定时关机

原文地址: https://www.cveoy.top/t/topic/mI4E 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录