Johan Bresler
Johan Bresler

Reputation: 6508

Get Application exe size easily

Is there a way in Delphi to get the currect application's exe size in one or two lines of code?

Upvotes: 7

Views: 2582

Answers (9)

tz.
tz.

Reputation: 749

uses IdGlobalProtocols;

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

Upvotes: 2

Daniel Rikowski
Daniel Rikowski

Reputation: 72514

Unfortunatly it is not possible to do that with only one or two lines of code without using some library.

The easy part is getting the application's exe file. You can find it in Application.ExeName

In general there are several possibilities for retrieving the file size:

  1. Open the file and read the size of the stream. This can be accomplished using the 'old' Delphi functions FileOpen and FileSize, or with TFileStream (use the size property) or with Win32 API functions CreateFile and GetFileSize function. (Platform dependend!) Make sure you open the file with read-only access.
  2. In a pure Win32 envinronment you can use FindFirst to get the file size. You can read it from TSearchRec.FindData.nFileSizeLow. If you want to be prepared for files larger than 2 GB (you should be) you have to use also the nFileSizeHigh part.
  3. In Delphi.NET you can use the System.IO.FileInfo, like this: FileInfo.Create(filename).Length (one-liner)
  4. In Linux you can use the lstat64 function (Unit Libc) and get the size from TStatBuf64.st_size. (two-liner if you don't count the variable declaration)

In the JCL library you can find many useful functions, including a simple function which returns the file size of a given file name. (It uses a method which suits the given platform)

Upvotes: 2

JosephStyons
JosephStyons

Reputation: 58685

Shortest I could do. Note that the .Size is in bytes, so for kilobytes, divide by 1024.

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

Check out this link.

Upvotes: 0

Mohammed Nasman
Mohammed Nasman

Reputation: 11050

I would like to modify the code provided by skamradt, to make it two lines of code as you requested ;-)

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

but I would prefer to use the code as skamradt wrote, because it's more safe

Upvotes: 0

Jozz
Jozz

Reputation: 608

For the sake of future compatibility, you should choose an implementation that does not require pointers or Windows API functions when possible. The TFileStream based solution provided by skamradt looks good to me.

But... You shouldn't worry too much whether the routine is 1 or 10 lines of code, because you're going to encapsulate it anyway in a function that takes a filename as a parameter and returns an Int64, and put it in your personal library of reusable code. Then you can call it like so:

GetMyFileSize(Application.ExeName);

Upvotes: 4

Robert K
Robert K

Reputation: 30328

It's not as small as you want, but it needs no handles. I use this in all my "SFX" archivers and programs that must know their size. IIRC it requires the Windows unit.

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;

Upvotes: 6

gabr
gabr

Reputation: 26830

Streams can also be used without a TFileStream variable:

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

Ugly, yes.

I prefer using DSiFileSize from DSiWin32. It uses CreateFile internally:

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 }

Upvotes: 2

skamradt
skamradt

Reputation: 15538

Just for grins...you can also do this with streams Just slightly more than 2 lines of code. Generally the application filename including path is also stored into Paramstr(0).

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

Upvotes: 11

You can try this:

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

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

Upvotes: 2

Related Questions