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

Delphi 實作跨平台定時自動關機程式:支援 Win9x 到 WinXP/2000/NT

     編輯:Delphi

伺服器或無人值守工作站常需在指定時間自動關機。本程式支援 Windows 95/98/Me 與 NT/2000/XP 兩大核心架構,功能包含:時間驗證、倒數提醒、強制關機、取消關機、托盤常駐、單一實例、攔截系統關機訊息讓使用者決定是否允許關閉。完整源碼附於文末。

核心功能架構

功能Win 9x 實作NT/2000/XP 實作
關機 APIExitWindowsEx(EWX_SHUTDOWN+EWX_FORCE, 0)OpenProcessToken → AdjustTokenPrivileges(SeShutdownPrivilege) → InitiateSystemShutdown
倒數顯示自訂視窗置頂顯示系統內建倒數對話框
取消關機停止 TimerAbortSystemShutdown(電腦名)

關鍵技術細節

1. 作業系統版本判斷


function GetOSVersion: String;
var OSVer: TOSVersionInfo;
begin
  OSVer.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
  if GetVersionEx(OSVer) then
    case OSVer.dwPlatformId of
      VER_PLATFORM_WIN32_NT: Result := 'Windows NT/2000/XP';
      VER_PLATFORM_WIN32_WINDOWS: Result := 'Windows 95/98/Me';
    end;
end;

2. 取得關機特權 (NT 核心必須)


function EnableShutdownPriv: Boolean;
var hToken: THandle; TP: TOKEN_PRIVILEGES; RetLen: DWORD;
begin
  Result := False;
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then begin
    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, RetLen);
    end;
    CloseHandle(hToken);
  end;
end;

3. 托盤圖示與右鍵選單


procedure ShowInTray;
begin
  Tray.cbSize := SizeOf(Tray);
  Tray.Wnd := Handle;
  Tray.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
  Tray.uCallbackMessage := WM_USER;
  Tray.hIcon := Application.Icon.Handle;
  Tray.szTip := '定時關機';
  Shell_NotifyIcon(NIM_ADD, @Tray);
end;

procedure TrayMenu(var Msg: TMessage);
var Pt: TPoint;
begin
  if Msg.LParam = WM_RBUTTONDOWN then begin
    GetCursorPos(Pt);
    PopupMenu1.Popup(Pt.X, Pt.Y);
  end;
end;

4. 攔截系統關機訊息


procedure WMQueryEndSession(var Msg: TWMQueryEndSession); message WM_QUERYENDSESSION;
begin
  if MessageDlg('確定要關閉 Windows?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
    Msg.Result := 0  // 拒絕關機
  else
    Msg.Result := 1; // 允許關機
end;

5. 全域原子表確保單一實例


procedure FormCreate(Sender: TObject);
begin
  if GlobalFindAtom('AUTO_SHUTDOWN_APP') = 0 then
    Atom := GlobalAddAtom('AUTO_SHUTDOWN_APP')
  else begin
    ShowMessage('程式已在執行中!');
    Halt;
  end;
end;

procedure FormDestroy(Sender: TObject);
begin
  GlobalDeleteAtom(Atom);
  Shell_NotifyIcon(NIM_DELETE, @Tray);
end;

完整單元代碼結構 (AutoShut1.pas)


unit AutoShut1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, Menus, AppEvnts, ShellAPI;

type TForm1 = class(TForm)
  Timer1, Timer2: TTimer;
  ApplicationEvents1: TApplicationEvents;
  PopupMenu1: TPopupMenu;
  Edit1, Edit2: TEdit;  // 目前時間、設定關機時間
  Label1, Label2, Label3: TLabel;
  Btn_OK, Btn_Abort: TButton;
  procedure Timer1Timer(Sender: TObject);
  procedure Timer2Timer(Sender: TObject);
  procedure Btn_OKClick(Sender: TObject);
  procedure Btn_AbortClick(Sender: TObject);
  procedure TimeSetClick(Sender: TObject);
  procedure ExitClick(Sender: TObject);
  procedure Edit2KeyPress(Sender: TObject; var Key: Char);
  procedure WMQueryEndSession(var Msg: TWMQueryEndSession); message WM_QUERYENDSESSION;
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
  procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  procedure TrayMenu(var Msg: TMessage); message WM_USER;
private
  Tray: NOTIFYICONDATA;
  procedure ShowInTray;
public
end;

var Form1: TForm1; Atom: Integer; TimeDelay: Integer;
implementation
{$R *.dfm}
// ... 上述所有函數實作 ...
// 關鍵邏輯:
// Timer1: 每秒更新目前時間,比對 Edit2 設定時間
// Timer2: 觸發後 30 秒倒數,到期執行關機
// Btn_OK: 驗證時間格式 HH:MM,通過則最小化至托盤
// Btn_Abort: 取消關機 (NT 呼叫 AbortSystemShutdown)
// Edit2KeyPress: Enter 觸發 Btn_OK
end.

部署與測試

  • Delphi 6 / Windows XP 開發編譯。
  • 實測 Win95/98/Me、NT4/2000/XP 均正常運作。
  • 需以管理員權限執行才能在 NT 核心取得關機特權。

此程式展示 Delphi 呼叫 Win32 API 處理系統級任務的典型模式:版本分支、特權提升、訊息攔截、托盤常駐、單一實例,可直接套用於其他系統管理工具開發。

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