Domanda

Esiste un modo in Delphi per ottenere la dimensione exe dell'applicazione corrente in una o due righe di codice?

È stato utile?

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:

  1. Apri il file e leggi le dimensioni del flusso. Ciò può essere realizzato utilizzando le "vecchie" funzioni Delphi FileOpen e FileSize , oppure con TFileStream (usa la size proprietà) o con le funzioni API Win32 CreateFile e GetFileSize . (Dipendente dalla piattaforma!) Assicurati di aprire il file con accesso di sola lettura.
  2. In un ambiente Win32 puro puoi usare FindFirst per ottenere le dimensioni del file. Puoi leggerlo da TSearchRec.FindData.nFileSizeLow . Se vuoi essere pronto per file più grandi di 2 GB (dovresti essere) devi usare anche la parte nFileSizeHigh .
  3. In Delphi.NET è possibile utilizzare System.IO.FileInfo , in questo modo: FileInfo.Create (nome file). Lunghezza (one-liner)
  4. In Linux è possibile utilizzare la funzione lstat64 (Unità Libc ) e ottenere le dimensioni da TStatBuf64.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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top