170 lines
5.3 KiB
ObjectPascal
170 lines
5.3 KiB
ObjectPascal
//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.
|