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

Delphi 打造隱蔽後台監控程式:註冊系統服務與全域熱鍵喚醒

     編輯:Delphi

需求背景

開發後台監控、記錄器或防竊軟體時,常需滿足三個條件:

  1. 正常執行時不顯示在工作列。
  2. Ctrl+Alt+Del 叫出的工作管理員「應用程式」頁籤也不顯示(Windows 9x 時代)。
  3. 管理員可透過預設熱鍵(如 Ctrl+Alt+R)喚醒介面進行設定或查看日誌。

本文示範在 Delphi 5/6/7 於 Windows 98 環境下,利用 RegisterServiceProcess 將進程偽裝為系統服務,並配合 RegisterHotKey 實現全域熱鍵喚醒。

核心 API 與常數

const
  RSP_SIMPLE_SERVICE = 1;

function RegisterServiceProcess(dwProcessID, dwType: DWORD): DWORD; stdcall;
  external 'KERNEL32.DLL';

RegisterServiceProcess(GetCurrentProcessID, RSP_SIMPLE_SERVICE) 可將目前進程從工作管理員的應用程式清單移除(僅限 Windows 9x)。

全域熱鍵實作步驟

  1. 宣告訊息處理函式:procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
  2. 建立全域原子取得唯一 ID:id := GlobalAddAtom('MyHotkey');
  3. 註冊熱鍵:RegisterHotKey(Handle, id, MOD_CONTROL + MOD_ALT, VK_R);
  4. 在 WMHotKey 中判斷 Msg.HotKey = id 並顯示表單。
  5. 表單關閉時解除註冊:UnregisterHotKey + GlobalDeleteAtom。

完整單元程式碼

unit Unit1;

interface

uses
  Windows, Messages, Forms, Dialogs, Classes, Controls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;  { 隱藏為服務 }
    Button2: TButton;  { 正常關閉 }
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    id: Integer;                       { 熱鍵 ID }
    procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const
  RSP_SIMPLE_SERVICE = 1;
  MOD_ALT     = 1;
  MOD_CONTROL = 2;
  VK_R        = 82;

function RegisterServiceProcess(dwProcessID, dwType: DWORD): DWORD; stdcall;
  external 'KERNEL32.DLL';

{ 熱鍵訊息處理 }
procedure TForm1.WMHotKey(var Msg: TWMHotKey);
begin
  if Msg.HotKey = id then
  begin
    ShowMessage('偵測到熱鍵 Ctrl+Alt+R 被按下!');
    Form1.Visible := True;            { 喚醒主視窗 }
    Form1.WindowState := wsNormal;    { 確保非最小化 }
    Form1.BringToFront;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  { 防止多重啟動:檢查原子是否已存在 }
  if GlobalFindAtom('MyHotkey') = 0 then
  begin
    id := GlobalAddAtom('MyHotkey');
    RegisterHotKey(Handle, id, MOD_CONTROL + MOD_ALT, VK_R);
  end
  else
    Halt;  { 已有實例在跑,直接結束 }
end;

{ 註冊為系統服務並隱藏 }
procedure TForm1.Button1Click(Sender: TObject);
begin
  RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE);
  Form1.Hide;
end;

{ 正常關閉程式 }
procedure TForm1.Button2Click(Sender: TObject);
begin
  Close;
end;

{ 表單關閉時清理資源 }
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UnregisterHotKey(Handle, id);
  GlobalDeleteAtom(id);
end;

end.

關鍵點補充

  • 防重複啟動:FormCreate 中以 GlobalFindAtom 檢查同名原子,若存在即 Halt,比 Mutex 更輕量(但僅限同 Session)。
  • 熱鍵衝突:若 Ctrl+Alt+R 被其他軟體佔用,RegisterHotKey 會失敗(回傳 False),建議改用較罕見組合(如 Ctrl+Alt+Shift+F12)。
  • Windows 版本限制:RegisterServiceProcess 僅在 Windows 95/98/Me 有效。NT 核心系統請改用真正的 Windows Service(CreateService + StartServiceCtrlDispatcher)或將主視窗 Visible := False、ShowInTaskBar := stNever、SetWindowLong(Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW) 隱藏工作列圖示。
  • 管理員權限:Vista 以降註冊全域熱鍵需管理員權限,建議在 Manifest 中加入 requireAdministrator。

現代化替代方案(Windows 2000+)

{ 隱藏工作列圖示 }
Application.ShowMainForm := False;
Form1.ShowInTaskBar := stNever;
SetWindowLong(Form1.Handle, GWL_EXSTYLE,
  GetWindowLong(Form1.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);

{ 真正的 Windows Service 專案範本 }
{ File > New > Other > Service Application }

結語

雖然 RegisterServiceProcess 已成歷史,但「全域熱鍵 + 隱藏主視窗」的架構思維在現代 Delphi 開發中依然通用。掌握 WM_HOTKEY、GlobalAddAtom、RegisterHotKey 的協作流程,能為各類常駐後台工具(截圖、翻譯、剪貼簿增強、快捷啟動器)提供堅實基礎。

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