unit FileHelper;
{$mode ObjFPC}{$H+}
interface
uses
Windows, SysUtils;
function MoveData(const Src, Dst: WideString; Func: Integer; FileOverwrite: Boolean = True): Boolean;
implementation
const
{FO_MOVE = $0001;
FO_COPY = $0002;
FO_DELETE = $0003;
FO_RENAME = $0004;}
FOF_NOCONFIRMMKDIR = $0200;
FOF_NOCONFIRMATION = $0010; { Don't prompt the user. }
FOF_SIMPLEPROGRESS = $0100; { means don't show names of files }
FOF_SILENT = $0004; { don't create progress/report }
type
TSHFileOpStructW = record
Wnd: HWND;
wFunc: UINT;
pFrom: LPCWSTR;
pTo: LPCWSTR;
fFlags: FILEOP_FLAGS;
fAnyOperationsAborted: BOOL;
hNameMappings: Pointer;
lpszProgressTitle: LPCWSTR;
end;
function MoveFileW(lpExistingFileName, lpNewFileName: PWideChar): BOOL; stdcall; external 'Kernel32.dll' name 'MoveFileW';
function CopyFileW(lpExistingFileName, lpNewFileName: PWideChar; bFailIfExists: BOOL): BOOL; stdcall; external 'Kernel32.dll' name 'CopyFileW';
{
function CopyFileW(lpExistingFileName:LPCWSTR; lpNewFileName:LPCWSTR; bFailIfExists:WINBOOL):WINBOOL; external 'kernel32' name 'CopyFileW';
function MoveFileW(lpExistingFileName:LPCWSTR; lpNewFileName:LPCWSTR):WINBOOL; external 'kernel32' name 'MoveFileW';
}
function SHFileOperationW(const lpFileOp: TSHFileOpStructW): Integer; stdcall; external 'shell32.dll' name 'SHFileOperationW';
function MoveDir(const Src, Dst: WideString; Func: Integer): Boolean;
var
FOS: TSHFileOpStructW;
begin
ZeroMemory(@FOS, SizeOf(FOS));
FOS.wFunc := Func; // FO_MOVE , FO_COPY;
FOS.fFlags := FOF_NOCONFIRMMKDIR or FOF_SIMPLEPROGRESS or FOF_NOCONFIRMATION or FOF_SILENT;
FOS.pFrom := PWideChar(IncludeTrailingPathDelimiter(Src) + '*.*'#0);
FOS.pTo := PWideChar(Dst + #0);
Result := (SHFileOperationW(FOS) = 0);
end;
// this method wants either a full source and destination path
// or a full source and destination path with "filename.ext"
// it return true on success or false on failure
function MoveData(const Src, Dst: WideString; Func: Integer; FileOverwrite: Boolean = True): Boolean;
begin
Result := False;
if FileExists(Src) then
begin
Result := ForceDirectories(ExtractFilePath(Dst));
if Result then
begin
if (FileOverwrite and FileExists(Dst)) then
Result := ((SetFileAttributesW(PWideChar('\\?\' + Dst), faNormal)) and DeleteFileW(PWideChar('\\?\' + Dst)));
if Result then
begin
if Func = $0001 then Result := MoveFileW(PWideChar('\\?\' + Src), PWideChar('\\?\' + Dst)); // move
if Func = $0002 then Result := CopyFileW(PWideChar('\\?\' + Src), PWideChar('\\?\' + Dst), false); // copy
end;
end;
end
else
if DirectoryExists(Src) then
begin
Result := MoveDir(Src, Dst, Func);
if Result then
begin
if Func = $0001 then Result := RemoveDir(Src); // only remove empty folder when using FO_MOVE
//Result := RemoveDir(Src);
end;
end;
end;
end.