7

Delphi 有没有办法在一两行代码中获取当前应用程序的 exe 大小?

4

9 回答 9

11

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;
于 2008-10-20T14:34:36.373 回答
5

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;
于 2008-10-20T15:27:50.477 回答
4

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

于 2008-10-21T00:14:07.000 回答
2

不幸的是,如果不使用某些库,只用一两行代码是不可能做到的。

简单的部分是获取应用程序的 exe 文件。你可以在Application.ExeName

一般来说,检索文件大小有几种可能性:

  1. 打开文件并读取流的大小。这可以使用“旧”Delphi 函数FileOpenFileSize,或使用TFileStream(使用size属性)或使用 Win32 API 函数CreateFileGetFileSize函数来完成。(平台依赖!)确保您以只读访问权限打开文件。
  2. 在纯 Win32 环境中,您可以使用它FindFirst来获取文件大小。您可以从TSearchRec.FindData.nFileSizeLow. 如果您想为大于 2 GB 的文件做好准备(您应该这样做),您还必须使用该nFileSizeHigh部分。
  3. 在 Delphi.NET 中,您可以System.IO.FileInfo像这样使用 : FileInfo.Create(filename).Length(one-liner)
  4. 在 Linux 中,您可以使用lstat64函数 (Unit Libc) 并从TStatBuf64.st_size. (如果不计算变量声明,则为双线)

JCL 库中,您可以找到许多有用的函数,包括一个返回给定文件名的文件大小的简单函数。(它使用适合给定平台的方法)

于 2008-10-20T09:02:50.397 回答
2

你可以试试这个:

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

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

于 2008-10-20T09:18:29.740 回答
2

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 }
于 2008-10-20T15:07:56.977 回答
2
uses IdGlobalProtocols;

var
  ExeSize: Int64;
begin
  ExeSize := FileSizeByName(ParamStr(0)); 
  // or
  ExeSize := FileSizeByName(Application.ExeName);
end;
于 2012-08-04T11:29:17.080 回答
0

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

于 2008-10-21T12:11:53.803 回答
0

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.

于 2008-10-21T12:47:38.570 回答