BSOne.SFC/Tocsg.Lib/VCL/Tocsg.Delete.pas

267 lines
7.0 KiB
Plaintext

{*******************************************************}
{ }
{ 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.