Delphi 实现定时关机
可以使用 Windows API 中的 ExitWindowsEx 函数来实现定时关机。
具体步骤如下:
-
定义一个 TTimer 组件,设置其时间间隔为一分钟。在每次 Timer 的 OnTimer 事件中,将剩余时间减 1 秒并更新界面上的倒计时显示。
-
在界面上添加一个按钮,点击按钮时,先调用 Windows API 中的 OpenProcessToken 函数获取当前进程的令牌(token),然后调用 AdjustTokenPrivileges 函数启用关机权限。
-
在需要定时关机的时候,调用 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.
原文地址: https://www.cveoy.top/t/topic/mI4E 著作权归作者所有。请勿转载和采集!