//version 0.31 beta unit FileUtilsEx; {$MODE Delphi} {$codepage UTF8} interface uses windows, sysutils, ShellApi, Classes; type TExePlatform = (expUnknown, exp32Bit, exp64Bit, expOther); //stdcalls function FileVersion (AFileName: String): String; function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String; const ADecimalPlaces: Byte): String; Stdcall; Overload; function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String): String; Stdcall; Overload; function FileSize2Str (const AFileSize: Int64; const ADecimalPlaces: Byte): String; Overload; function FileSize2Str (const AFileSize: Int64): String; Overload; function FileAccessDateToDateTime (FileTime: TFILETIME): TDateTime; Stdcall; function RenameDir (const DirName, NewName: String): Boolean; STDCALL; function GetEXEPlatform (const AFileName: String): TExePlatform; STDCALL; implementation const AFileSizeNames: Array[0..4] of String = ('Byte', 'KB', 'MB', 'GB', 'TB'); //Getting version of the file function FileVersion (AFileName: String): String; var szName: array[0..255] of Char; P: Pointer; Value: Pointer; Len: UINT; GetTranslationString: String; FFileName: PChar; FValid:boolean; FSize: DWORD; FHandle: DWORD; FBuffer: PChar; begin try FFileName:= StrPCopy(StrAlloc(Length(AFileName) + 1), AFileName); FValid:= False; FSize:= GetFileVersionInfoSize(FFileName, FHandle); if FSize > 0 then try GetMem(FBuffer, FSize); FValid:= GetFileVersionInfo(FFileName, FHandle, FSize, FBuffer); except FValid:= False; raise; end; Result:= ''; if FValid then VerQueryValue(FBuffer, '\VarFileInfo\Translation', P, Len) else P:= nil; if P <> nil then GetTranslationString:= IntToHex(MakeLong(HiWord(Longint(P^)), LoWord(Longint(P^))), 8); if FValid then begin StrPCopy(szName, '\StringFileInfo\' + GetTranslationString + '\FileVersion'); if VerQueryValue(FBuffer, szName, Value, Len) then Result:= StrPas(PChar(Value)); end; finally try if FBuffer <> nil then FreeMem(FBuffer, FSize); except end; try StrDispose(FFileName); except end; end; end; //FileSize2Str function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String; const ADecimalPlaces: Byte): String; Overload; function FrmtSize (const ASize, ADelim: Int64; const ADP: Byte): String; var VDelim: Int64; Indx: Byte; begin VDelim:= 1; for Indx:= 0 to ADP do VDelim:= VDelim*10; Result:= FloatToStr(round((ASize*VDelim)/ADelim)/VDelim); end; const AFrmtsStr: String = '%s %s'; begin //Bytes if AFileSize < 1024 then Result:= Format(AFrmtsStr, [IntToStr(AFileSize), AStringNames[0]]); //KiloBytes if (AFileSize >= 1024) and (AFileSize < 1048576) then Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1024, ADecimalPlaces), AStringNames[1]]); //MegaBytes if (AFileSize >= 1048576) and (AFileSize < 1073741824) then Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1048576, ADecimalPlaces), AStringNames[2]]); //GigaBytes if (AFileSize >= 1073741824) and (AFileSize < 1099511627776) then Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1073741824, ADecimalPlaces), AStringNames[3]]); //TeraBytes if (AFileSize >= 1099511627776) then Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1073741824, ADecimalPlaces), AStringNames[4]]); end; function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String): String; Overload; begin Result:= FileSize2Str(AFileSize, AStringNames, 2); end; function FileSize2Str (const AFileSize: Int64; const ADecimalPlaces: Byte): String; Overload; begin Result:= FileSize2Str(AFileSize, AFileSizeNames, ADecimalPlaces); end; function FileSize2Str (const AFileSize: Int64): String; Overload; begin Result:= FileSize2Str(AFileSize, AFileSizeNames, 2); end; //FileAccessDateToDateTime //Author: Дураг (http://www.sql.ru/forum/memberinfo.aspx?mid=32731) from http://www.sql.ru/forum/259218/kak-poluchit-datu-i-vremya-sozdaniya-fayla function FileAccessDateToDateTime (FileTime: TFILETIME): TDateTime; var LocalTime: TFILETIME; DOSFileTime: DWORD; begin FileTimeToLocalFileTime(FileTime, LocalTime); FileTimeToDosDateTime(LocalTime, LongRec(DOSFileTime).Hi, LongRec(DOSFileTime).Lo); Result:= FileDateToDateTime(DOSFileTime); end; //RenameDir function RenameDir (const DirName, NewName: String): Boolean; var shellinfo: TSHFILEOPSTRUCT; DirFrom, DirTo: String; begin DirFrom:= DirName; DirTo:= NewName; with shellinfo do begin Wnd:= 0; wFunc:= FO_RENAME; pFrom:= PChar(DirFrom); pTo:= PChar(DirTo); fFlags:= FOF_FILESONLY or FOF_ALLOWUNDO or FOF_SILENT or FOF_NOCONFIRMATION; end; SHFileOperation(shellinfo); Result:= DirectoryExists(NewName); end; //GetEXEPlatform //Author Dmitry Arefiev (http://www.sql.ru/forum/808857/kak-opredelit-razryadnost-prilozheniya) function GetEXEPlatform (const AFileName: String): TExePlatform; var oFS: TFileStream; iPeOffset: Integer; iPeHead: LongWord; iMachineType: Word; begin Result:= expUnknown; try oFS:= TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone); try oFS.Seek($3C, soFromBeginning); oFS.Read(iPeOffset, SizeOf(iPeOffset)); oFS.Seek(iPeOffset, soFromBeginning); oFS.Read(iPeHead, SizeOf(iPeHead)); if iPeHead <> $00004550 then Exit; oFS.Read(iMachineType, SizeOf(iMachineType)); case iMachineType of $8664, $0200: Result:= exp64Bit; $014C: Result:= exp32Bit; else Result:= expOther; end; finally oFS.Free; end; except end; end; end.