Pergunta

Existe uma maneira em Delphi para obter o tamanho do exe do aplicativo atual em uma ou duas linhas de código?

Foi útil?

Solução

Apenas para sorrisos ... você também pode fazer isso com fluxos Apenas um pouco mais de 2 linhas de código. De um modo geral o nome do ficheiro pedido incluindo o caminho também é armazenada em ParamStr (0).

var
  fs : tFilestream;
begin
  fs := tFilestream.create(paramstr(0),fmOpenRead or fmShareDenyNone);
  try
    result := fs.size;
  finally
    fs.free;
  end;
end;

Outras dicas

Não é tão pequeno quanto você quiser, mas não precisa de alças. Eu uso isso em todos os meus programas de arquivamento "SFX" e programas que devem conhecer o seu tamanho. IIRC que exige a unidade do 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;

Por uma questão de compatibilidade futura, você deve escolher uma implementação que não requer ponteiros ou funções da API do Windows quando possível. A solução baseada TFileStream fornecido pelo skamradt parece bom para mim.

Mas ... Você não deve se preocupar muito se a rotina é 1 ou 10 linhas de código, porque você está indo para encapsulá-lo de qualquer maneira em uma função que leva um nome de arquivo como um parâmetro e retorna um Int64, e colocá-lo em sua biblioteca pessoal de código reutilizável. Depois, você pode chamá-lo assim:

GetMyFileSize (Application.ExeName);

Você pode tentar o seguinte:

  if FindFirst(ExpandFileName(Application.exename), faAnyFile, SearchRec) = 0 then
    MessageDlg(Format('Tamaño: <%d>',[SearchRec.Size]), mtInformation, [mbOK], 0);
  FindClose(SearchRec);

===============
Neftalí

Streams também pode ser usado sem uma variável TFileStream:

with TFilestream.create(paramstr(0), fmOpenRead or fmShareDenyNone) do 
  aFileSize := Size;
  Free;
end;

feio, sim.

Eu prefiro usar DSiFileSize de DSiWin32 . Ele usa 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 }

Infelizmente não é possível fazer isso com apenas uma ou duas linhas de código sem usar alguma biblioteca.

A parte mais fácil é obter exe do aplicativo. Você pode encontrá-lo em Application.ExeName

Em geral, existem várias possibilidades para recuperar o tamanho do arquivo:

  1. Abra o arquivo e ler o tamanho do fluxo. Isso pode ser feito usando o 'velho' Delphi funções FileOpen e FileSize ou com TFileStream (use a propriedade size) ou com Win32 API funções CreateFile e função GetFileSize. (Dependend Platform!) Certifique-se de abrir o arquivo com acesso somente leitura.
  2. Em um Win32 pura envinronment você pode usar FindFirst para obter o tamanho do arquivo. Você pode lê-lo do TSearchRec.FindData.nFileSizeLow. Se você quer estar preparado para arquivos maiores que 2 GB (você deveria ser) você tem que usar também a parte nFileSizeHigh.
  3. Em Delphi.NET você pode usar o System.IO.FileInfo, como este: FileInfo.Create(filename).Length (one-liner)
  4. No Linux, você pode usar a função lstat64 (Unidade Libc) e obter o tamanho de TStatBuf64.st_size. (Two-liner, se você não contar a declaração de variável)

Na biblioteca JCL pode encontrar muitas funções úteis, incluindo uma função simples que retorna o tamanho do arquivo um determinado nome de arquivo. (Ele usa um método que ternos a plataforma dada)

uses IdGlobalProtocols;

var
  ExeSize: Int64;
begin
  ExeSize := FileSizeByName(ParamStr(0)); 
  // or
  ExeSize := FileSizeByName(Application.ExeName);
end;

Gostaria de modificar o código fornecido pelo skamradt, para torná-lo duas linhas de código que você solicitados; -)

  with tFilestream.create(paramstr(0),fmOpenRead or fmShareDenyNone) do
    ShowMessage(IntToStr(size));

mas eu preferiria usar o código como skamradt escreveu, porque é mais segura

Shortest eu poderia fazer. Note que o .size está em bytes, portanto, para kilobytes, dividir por 1024.

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TFileStream.Create(Application.ExeName,fmShareDenyNone) do
    ShowMessage(FloatToStr(Size/1024));
end;

Confira este link.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top