Ottieni facilmente le dimensioni dell'applicazione
Domanda
Esiste un modo in Delphi per ottenere la dimensione exe dell'applicazione corrente in una o due righe di codice?
Soluzione
Solo per i sorrisi ... puoi farlo anche con i flussi Poco più di 2 righe di codice. Generalmente il nome file dell'applicazione, incluso il percorso, viene anche memorizzato in Paramstr (0).
var
fs : tFilestream;
begin
fs := tFilestream.create(paramstr(0),fmOpenRead or fmShareDenyNone);
try
result := fs.size;
finally
fs.free;
end;
end;
Altri suggerimenti
Non è piccolo come vuoi, ma non ha bisogno di maniglie. Lo uso in tutto il mio " SFX " archivi e programmi che devono conoscere le loro dimensioni. IIRC richiede l'unità Windows.
function GetExeSize: cardinal; var p: pchar; i, NumSections: integer; const IMAGE_PE_SIGNATURE = $00004550; begin result := 0; p := pointer(hinstance); inc(p, PImageDosHeader(p)._lfanew + sizeof(dword)); NumSections := PImageFileHeader(p).NumberOfSections; inc(p,sizeof(TImageFileHeader)+ sizeof(TImageOptionalHeader)); for i := 1 to NumSections do begin with PImageSectionHeader(p)^ do if PointerToRawData+SizeOfRawData > result then result := PointerToRawData+SizeOfRawData; inc(p, sizeof(TImageSectionHeader)); end; end;
Per motivi di compatibilità futura, è necessario scegliere un'implementazione che non richieda puntatori o funzioni API di Windows quando possibile. La soluzione basata su TFileStream fornita da skamradt mi sta bene.
Ma ... Non dovresti preoccuparti troppo se la routine è 1 o 10 righe di codice, perché lo incapsulerai comunque in una funzione che prende un nome file come parametro e restituisce un Int64, e inseriscilo nella tua libreria personale di codice riutilizzabile. Quindi puoi chiamarlo così:
GetMyFileSize (Application.ExeName);
Puoi provare questo:
if FindFirst(ExpandFileName(Application.exename), faAnyFile, SearchRec) = 0 then
MessageDlg(Format('Tamaño: <%d>',[SearchRec.Size]), mtInformation, [mbOK], 0);
FindClose(SearchRec);
===============
Neftalí
Gli stream possono anche essere usati senza una variabile TFileStream:
with TFilestream.create(paramstr(0), fmOpenRead or fmShareDenyNone) do
aFileSize := Size;
Free;
end;
Brutto, sì.
Preferisco usare DSiFileSize da DSiWin32 . Utilizza CreateFile internamente:
function DSiFileSize(const fileName: string): int64;
var
fHandle: DWORD;
begin
fHandle := CreateFile(PChar(fileName), 0, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if fHandle = INVALID_HANDLE_VALUE then
Result := -1
else try
Int64Rec(Result).Lo := GetFileSize(fHandle, @Int64Rec(Result).Hi);
finally CloseHandle(fHandle); end;
end; { DSiFileSize }
Sfortunatamente non è possibile farlo con solo una o due righe di codice senza usare alcune librerie.
La parte facile è ottenere il file exe dell'applicazione. Puoi trovarlo in Application.ExeName
In generale ci sono diverse possibilità per recuperare le dimensioni del file:
- Apri il file e leggi le dimensioni del flusso. Ciò può essere realizzato utilizzando le "vecchie" funzioni Delphi
FileOpen
eFileSize
, oppure conTFileStream
(usa lasize
proprietà) o con le funzioni API Win32CreateFile
eGetFileSize
. (Dipendente dalla piattaforma!) Assicurati di aprire il file con accesso di sola lettura. - In un ambiente Win32 puro puoi usare
FindFirst
per ottenere le dimensioni del file. Puoi leggerlo daTSearchRec.FindData.nFileSizeLow
. Se vuoi essere pronto per file più grandi di 2 GB (dovresti essere) devi usare anche la partenFileSizeHigh
. - In Delphi.NET è possibile utilizzare
System.IO.FileInfo
, in questo modo:FileInfo.Create (nome file). Lunghezza
(one-liner) - In Linux è possibile utilizzare la funzione
lstat64
(UnitàLibc
) e ottenere le dimensioni daTStatBuf64.st_size
. (due righe se non conti la dichiarazione delle variabili)
Nella libreria JCL puoi trovare molte funzioni utili, inclusa una semplice funzione che restituisce la dimensione del file di un nome file specificato. (Utilizza un metodo adatto alla piattaforma specificata)
uses IdGlobalProtocols;
var
ExeSize: Int64;
begin
ExeSize := FileSizeByName(ParamStr(0));
// or
ExeSize := FileSizeByName(Application.ExeName);
end;
Vorrei modificare il codice fornito da skamradt, per renderlo due righe di codice come richiesto ;-)
with tFilestream.create(paramstr(0),fmOpenRead or fmShareDenyNone) do
ShowMessage(IntToStr(size));
ma preferirei usare il codice come skamradt , perché è più sicuro
Il più breve che potessi fare. Si noti che .Size è in byte, quindi per i kilobyte, dividere per 1024.
procedure TForm1.Button1Click(Sender: TObject);
begin
with TFileStream.Create(Application.ExeName,fmShareDenyNone) do
ShowMessage(FloatToStr(Size/1024));
end;
Dai un'occhiata a questo link.