Delphi 有没有办法在一两行代码中获取当前应用程序的 exe 大小?
9 回答
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;
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);
不幸的是,如果不使用某些库,只用一两行代码是不可能做到的。
简单的部分是获取应用程序的 exe 文件。你可以在Application.ExeName
一般来说,检索文件大小有几种可能性:
- 打开文件并读取流的大小。这可以使用“旧”Delphi 函数
FileOpen
和FileSize
,或使用TFileStream
(使用size
属性)或使用 Win32 API 函数CreateFile
和GetFileSize
函数来完成。(平台依赖!)确保您以只读访问权限打开文件。 - 在纯 Win32 环境中,您可以使用它
FindFirst
来获取文件大小。您可以从TSearchRec.FindData.nFileSizeLow
. 如果您想为大于 2 GB 的文件做好准备(您应该这样做),您还必须使用该nFileSizeHigh
部分。 - 在 Delphi.NET 中,您可以
System.IO.FileInfo
像这样使用 :FileInfo.Create(filename).Length
(one-liner) - 在 Linux 中,您可以使用
lstat64
函数 (UnitLibc
) 并从TStatBuf64.st_size
. (如果不计算变量声明,则为双线)
在JCL 库中,您可以找到许多有用的函数,包括一个返回给定文件名的文件大小的简单函数。(它使用适合给定平台的方法)
你可以试试这个:
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 }
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.