{*******************************************************} { } { Tocsg.Delete } { } { Copyright (C) 2022 sunk } { } {*******************************************************} unit Tocsg.Delete; interface uses System.SysUtils, System.Classes, ADODB2000; function DeleteFileSelf(sPath: String = ''; aAddList: TStringList = nil): String; function PerfectDeleteFile(sPath: String; nOvrCnt: Integer = 1; bDetail: Boolean = false; sTmpDirName: String = ''): Boolean; procedure ClearRecentFolder(sUName: String = ''); procedure ClearAutoJumpLists(sUName: String = ''; bIgrFav: Boolean = true); procedure ClearUserTempFolder(bKvTmpOnly: Boolean = true); implementation uses Tocsg.Strings, Tocsg.Path, Tocsg.Safe, Winapi.Windows, Tocsg.Shell, Tocsg.Files; function DeleteFileSelf(sPath: String = ''; aAddList: TStringList = nil): String; var sName, sRName, sCmdSelfDel: String; CmdList: TStringList; i: Integer; begin Result := ''; if sPath = '' then sPath := GetRunExePath; sName := ExtractFileName(sPath); sRName := GetRandomStr(4, 8); sPath := ExtractFilePath(sPath); Guard(CmdList, TStringList.Create); CmdList.Add('timeout 1'); CmdList.Add(Format('taskkill /f /pid %d', [GetCurrentProcessId])); CmdList.Add('timeout 1'); CmdList.Add(Format('taskkill /f /pid %d', [GetCurrentProcessId])); CmdList.Add('timeout 1'); CmdList.Add(Format('cd "%s"', [sPath])); // CmdList.Add(Format('ren ".\%s" "%s"', [sName, sRName])); CmdList.Add('timeout 1'); // CmdList.Add(Format('del "%s"', [sRName])); CmdList.Add(Format('del .\"%s"', [sName])); CmdList.Add('timeout 1'); if aAddList <> nil then for i := 0 to aAddList.Count - 1 do begin CmdList.Add(Format('del "%s"', [aAddList[i]])); end; sCmdSelfDel := Format('$d-%s.cmd', [GetRandomStr(4, 6)]); CmdList.Add(Format('del ".\%s"', [sCmdSelfDel])); try Result := sPath + sCmdSelfDel; CmdList.SaveToFile(Result); except exit; end; Sleep(500); // ExecuteAppAsUser(GetCurrentProcessId, 'cmd.exe', Format('/C "%s"', [sPath + sCmdSelfDel]), SW_HIDE); ExecutePath_hide('cmd.exe', Format('/C "%s"', [sPath + sCmdSelfDel])); end; function PerfectDeleteFile(sPath: String; nOvrCnt: Integer = 1; bDetail: Boolean= false; sTmpDirName: String = ''): Boolean; const BUF_LEN = 65536; var fs: TFileStream; dwWrite: DWORD; arrBuf: array [0 .. BUF_LEN-1] of Byte; i: Integer; begin Result := false; if not FileExists(sPath) then exit; if nOvrCnt <= 0 then nOvrCnt := 1; try if bDetail then begin if sTmpDirName <> '' then begin // 위치 정보 변경 var sTmpPath: String := sPath[1] + ':\' + IncludeTrailingBackslash(sTmpDirName); // ':\@TmpPd\'; if ForceDirectories(sTmpPath) then begin sTmpPath := sTmpPath + GetRandomStr(5, 8); if MoveFile_wait(sPath, sTmpPath, 1) then sPath := sTmpPath; end; end; end; // 내용 삭제 fs := TFileStream.Create(sPath, fmOpenReadWrite); try for i := 0 to nOvrCnt - 1 do begin ZeroMemory(@arrBuf, BUF_LEN); fs.Position := 0; while fs.Size > fs.Position do begin if BUF_LEN > (fs.Size - fs.Position) then dwWrite := fs.Size - fs.Position else dwWrite := BUF_LEN; if fs.Write(arrBuf, dwWrite) <> dwWrite then break; end; end; if bDetail then begin // 크기 초기화 fs.Size := 0; end; finally fs.Free; end; if bDetail then begin // 시간 정보 초기화 SetFileDateTime(sPath, 0, 0, 0); end; except // on E: Exception do // ETgException.TraceException(E, 'Fail .. PerfectDeleteFile()'); end; Result := DeleteFileForce(sPath); end; procedure ClearRecentFolder(sUName: String = ''); var sDir: String; FileList: TStringList; i: Integer; begin if sUName = '' then begin sDir := GetUserDir + 'AppData\Roaming\Microsoft\Windows\Recent\' end else begin sDir := GetWindowsDir; if sDir = '' then exit; sDir := sDir[1] + Format(':\Users\%s\AppData\Roaming\Microsoft\Windows\Recent\', [sUName]); end; if DirectoryExists(sDir) then begin Guard(FileList, TStringList.Create); ExtrFilesFromDir(sDir, FileList, false, 'lnk'); for i := 0 to FileList.Count - 1 do DeleteFile(PChar(sDir + FileList[i])); // DeleteDirSub(sDir, false); // 이렇게 하면 즐겨 찾기까지 모두 삭제됨 23_1219 16:50:53 kku end; end; procedure ClearAutoJumpLists(sUName: String = ''; bIgrFav: Boolean = true); var sDir: String; FileList: TStringList; i: Integer; begin if sUName = '' then begin sDir := GetUserDir + 'AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\' end else begin sDir := GetWindowsDir; if sDir = '' then exit; sDir := sDir[1] + Format(':\Users\%s\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\', [sUName]); end; if DirectoryExists(sDir) then begin Guard(FileList, TStringList.Create); if bIgrFav then FileList.Add('f01b4d95cf55d32a.automaticDestinations-ms'); // 즐겨찾기 제외 DeleteDirSub(sDir, false, false, FileList); end; end; procedure ClearUserTempFolder(bKvTmpOnly: Boolean = true); var sWinDir, sUsersDir: String; UserList: TStringList; i: Integer; procedure ClearWinTempKvOnly; var wfd: TWin32FindData; hSc: THandle; sDir, sPath, sFName: String; begin sDir := sWinDir + 'Temp\'; sPath := sDir + '*.*'; hSc := FindFirstFile(PChar(sPath), wfd); if hSc = INVALID_HANDLE_VALUE then exit; try Repeat if (String(wfd.cFileName) <> '.') and (String(wfd.cFileName) <> '..') then if ((wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) then begin if UpperCase(wfd.cFileName).StartsWith('KV_') then DeleteDir(sDir + wfd.cFileName); end else begin sFName := UpperCase(wfd.cFileName); if GetFileExt(sFName) = 'TMP' then begin if sFName.StartsWith('KP') or sFName.StartsWith('KV') or sFName.StartsWith('KY') then DeleteFile(PChar(sDir + wfd.cFileName)); end; end; Until not FindNextFile(hSc, wfd); finally WinApi.Windows.FindClose(hSc); end; end; begin sWinDir := GetWindowsDir; if sWinDir = '' then exit; sUsersDir := sWinDir[1] + ':\Users\'; if not DirectoryExists(sUsersDir) then exit; Guard(UserList, TStringList.Create); ExtrDirFromDir(sUsersDir, UserList); for i := 0 to UserList.Count - 1 do DeleteDirSub(Format('%s\AppData\Local\Temp\', [sUsersDir + UserList[i]]), true, false, nil, true); if bKvTmpOnly then ClearWinTempKvOnly else DeleteDirSub(sWinDir + 'Temp\', true, false, nil, true); // 25_1021 13:31:14 kku end; end.