想在程式中靜默清空使用者回收站,不彈確認對話框、不顯示進度、不播放聲音?Shell32.dll 內建 SHEmptyRecycleBin 函數完美支援,透過 LoadLibrary/GetProcAddress 動態載入,避免靜態連結導致系統缺 DLL 無法啟動。本文提供完整實作代碼與旗標詳解。
function SHEmptyRecycleBin(
hwnd: HWND; // 父視窗句柄,用於模態對話框 (若啟用)
pszRootPath: PChar; // 根路徑,NULL 表示所有磁碟
dwFlags: DWORD // 行為旗標組合
): HRESULT; stdcall;
const
SHERB_NOCONFIRMATION = $00000001; // 不顯示確認對話框
SHERB_NOPROGRESSUI = $00000002; // 不顯示進度 UI
SHERB_NOSOUND = $00000004; // 不播放清空聲音
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private { Private declarations }
public { Public declarations }
end;
var Form1: TForm1;
implementation
{$R *.dfm}
const
SHERB_NOCONFIRMATION = $00000001;
SHERB_NOPROGRESSUI = $00000002;
SHERB_NOSOUND = $00000004;
type
TSHEmptyRecycleBin = function(Wnd: HWND; pszRootPath: PChar; dwFlags: DWORD): HRESULT; stdcall;
procedure TForm1.Button1Click(Sender: TObject);
var
EmptyRecycleBin: TSHEmptyRecycleBin;
LibHandle: THandle;
begin
// 1. 動態載入 Shell32.dll
LibHandle := LoadLibrary('Shell32.dll');
if LibHandle = 0 then begin
MessageDlg('無法載入 Shell32.dll', mtError, [mbOK], 0);
Exit;
end;
// 2. 取得函數位址
@EmptyRecycleBin := GetProcAddress(LibHandle, 'SHEmptyRecycleBinA');
if @EmptyRecycleBin = nil then begin
MessageDlg('找不到 SHEmptyRecycleBinA', mtError, [mbOK], 0);
FreeLibrary(LibHandle);
Exit;
end;
// 3. 呼叫清空回收站 (無確認、無進度、無聲音)
EmptyRecycleBin(Application.Handle, nil,
SHERB_NOCONFIRMATION or SHERB_NOPROGRESSUI or SHERB_NOSOUND);
// 4. 釋放資源
FreeLibrary(LibHandle);
@EmptyRecycleBin := nil;
end;
end.
| 方式 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 動態 LoadLibrary | DLL 缺失不會阻止程式啟動;可選擇性載入;支援插件架構 | 代碼稍長;需檢查函數指標有效性 | 系統 DLL、選用功能、跨版本相容 |
| 靜態 external | 呼叫語法簡潔;編譯器檢查參數 | DLL 缺失導致啟動失敗;版本綁定 | 核心依賴、自帶 DLL |
EmptyRecycleBin(Handle, 'D:\', Flags) 僅清空 D 槽回收站。S_OK (0) 成功,E_ACCESSDENIED 權限不足,E_INVALIDARG 參數錯誤。SHEmptyRecycleBinW,參數用 PWideChar。
// 取得回收站資訊
SHQueryRecycleBin(pszRootPath, var QueryRB: TSHQueryRB): HRESULT;
// TSHQueryRB = record i64Size: Int64; i64NumItems: Int64 end;
此技巧同樣適用於其他 Shell32 函數 (如 SHFileOperation、SHGetSpecialFolderPath),掌握動態載入模式,讓程式更健壯、部署更彈性。