Question

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

Was it helpful?

Solution

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;

OTHER TIPS

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;

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);

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í

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 }

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)

uses IdGlobalProtocols;

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

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top