SHFileOperation (Shell API) 提供高層級檔案操作:複製、移動、重命名、刪除 (可送回收筒)、帶進度 UI。核心結構 TSHFileOpStruct (對應 C SHFILEOPSTRUCT):
type
TSHFileOpStruct = record
hwnd: HWND; // 父視窗,用於進度對話框
wFunc: UINT; // 操作類型:FO_DELETE, FO_COPY, FO_MOVE, FO_RENAME
pFrom: PChar; // 來源路徑 (雙 null 結尾,可多路徑)
pTo: PChar; // 目標路徑 (同上)
fFlags: FILEOP_FLAGS; // 行為旗標:FOF_ALLOWUNDO(回收筒), FOF_SILENT(無提示), FOF_NOCONFIRMATION(不確認) 等
fAnyOperationsAborted: BOOL;
hNameMappings: Pointer;
lpszProgressTitle: PChar; // 進度標題
end;
uses ShellAPI;
procedure DeleteAdFolderToRecycleBin(const AdPath: string);
var
Op: TSHFileOpStruct;
DoubleNullPath: string;
begin
// 路徑必須以雙 null 結尾 (最後額外一個 #0)
DoubleNullPath := AdPath + #0#0;
FillChar(Op, SizeOf(Op), 0);
Op.hwnd := Application.Handle;
Op.wFunc := FO_DELETE;
Op.pFrom := PChar(DoubleNullPath);
Op.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT;
// FOF_ALLOWUNDO: 送回收筒而非永久刪除
// FOF_NOCONFIRMATION: 不彈出確認對話框
// FOF_SILENT: 不顯示進度 UI
if SHFileOperation(Op) <> 0 then
RaiseLastOSError; // 非 0 表失敗,取得系統錯誤碼
end;
程式下次啟動會自動重建 AD 資料夾並下載廣告。但若緊接著點擊「移除廣告」,可能因資料夾尚未建立完成導致錯誤。
保留資料夾結構,僅清空內容,避免時序競爭:
procedure RestoreAdsByClearingFiles(const AdPath: string);
var
SearchRec: TSearchRec;
FindResult: Integer;
FullPath: string;
begin
FindResult := FindFirst(IncludeTrailingPathDelimiter(AdPath) + '*.*', faAnyFile, SearchRec);
try
while FindResult = 0 do
begin
if (SearchRec.Attr and faDirectory) = 0 then // 僅刪除檔案,保留子目錄
begin
FullPath := IncludeTrailingPathDelimiter(AdPath) + SearchRec.Name;
if not DeleteFile(FullPath) then
// 記錄失敗...
end;
FindResult := FindNext(SearchRec);
end;
finally
FindClose(SearchRec);
end;
end;
廣告點擊本質是啟動 HTTP/HTTPS 連結。若目標程式硬編碼呼叫自家瀏覽器,檔案替換法無效。通用解法:確保系統 .html/http/https 關聯指向使用者慣用瀏覽器 (IE/Edge/Chrome)。
HKEY_CLASSES_ROOT\.html\(Default) = "htmlfile"
HKEY_CLASSES_ROOT\htmlfile\shell\open\command\(Default) = "C:\Program Files\Internet Explorer\iexplore.exe" %1
HKEY_CLASSES_ROOT\http\(Default) = "URL:HyperText Transfer Protocol"
HKEY_CLASSES_ROOT\http\shell\open\command\(Default) = "C:\Program Files\Internet Explorer\iexplore.exe" %1
HKEY_CLASSES_ROOT\https\(Default) = "URL:HyperText Transfer Protocol Secure"
HKEY_CLASSES_ROOT\https\shell\open\command\(Default) = "C:\Program Files\Internet Explorer\iexplore.exe" %1
uses Registry;
procedure SetHttpAssociationToIE;
var
Reg: TRegistry;
IePath: string;
begin
IePath := '"' + GetSystemDir + '\..\Program Files\Internet Explorer\iexplore.exe" %1';
Reg := TRegistry.Create(KEY_WRITE);
try
Reg.RootKey := HKEY_CLASSES_ROOT;
if Reg.OpenKey('http\shell\open\command', True) then
Reg.WriteString('', IePath);
if Reg.OpenKey('https\shell\open\command', True) then
Reg.WriteString('', IePath);
finally
Reg.Free;
end;
end;
注意:現代 Windows (Vista+) 因 UAC 與使用者選擇機制,程式修改關聯可能被覆蓋或無效。建議引導使用者在「設定 > 預設應用程式」手動設定。
FindFirst/FindNext/FindClose + CopyFile/DeleteFile 適合精細控制。SHFileOperation (或 Vista+ IFileOperation COM 介面) 更高層級。IncludeTrailingPathDelimiter、ExtractFilePath、ExpandFileName 避免手工拼接錯誤。