Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 轻松获取应用程序exe大小_Delphi_Size - Fatal编程技术网

Delphi 轻松获取应用程序exe大小

Delphi 轻松获取应用程序exe大小,delphi,size,Delphi,Size,Delphi中有没有一种方法可以在一行或两行代码中获取当前应用程序的exe大小?不幸的是,如果不使用某些库,仅使用一行或两行代码是不可能做到这一点的 最简单的部分是获取应用程序的exe文件。您可以在Application.ExeName 通常,检索文件大小有几种可能: 打开文件并读取流的大小。这可以使用“旧”Delphi函数FileOpen和FileSize,或使用TFileStream(使用size属性)或Win32 API函数CreateFile和GetFileSize函数来实现。(取决于平

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

不幸的是,如果不使用某些库,仅使用一行或两行代码是不可能做到这一点的

最简单的部分是获取应用程序的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
    (一行)
  • 在Linux中,您可以使用
    lstat64
    函数(Unit
    Libc
    ),并从
    TStatBuf64.st_size
    获取大小。(如果不计算变量声明,则为两行)
  • 在中,您可以找到许多有用的函数,包括一个返回给定文件名的文件大小的简单函数。(它使用适合给定平台的方法)

    您可以尝试以下方法:

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

    Neftalí

    仅用于咧嘴笑……您也可以使用略多于2行的代码流来实现这一点。通常,包括路径在内的应用程序文件名也存储在Paramstr(0)中


    也可以在不使用TFileStream变量的情况下使用流:

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

    我更喜欢使用DSiFileSize from。它在内部使用CreateFile:

    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 }
    

    它没有你想要的那么小,但不需要把手。我在我所有的“SFX”归档程序和程序中都使用了它,这些程序必须知道它们的大小。IIRC它需要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; 函数GetExeSize:基数; 变量 p:pchar; i、 NumSections:整数; 常数 图像签名=00004550美元; 开始 结果:=0; p:=指针(hinstance); 公司(p,PImageDosHeader(p)。_lfanew+sizeof(dword)); NumSections:=PImageFileHeader(p).NumberOfSections; inc(p,sizeof(TImageFileHeader)+sizeof(TImageOptionalHeader)); 对于i:=1到NumSections do 开始 带PImageSectionHeader(p)^do 如果指针torawdata+SizeOfRawData>result,则 结果:=指针指针指针数据+大小指针数据; 公司(p,sizeof(TImageSectionHeader)); 结束;
    结束 为了将来的兼容性,您应该尽可能选择不需要指针或Windows API函数的实现。skamradt提供的基于TFileStream的解决方案在我看来很不错

    但是。。。您不必太担心例程是1行还是10行代码,因为您无论如何都要将其封装在一个函数中,该函数将文件名作为参数并返回Int64,然后将其放入可重用代码的个人库中。那么你可以这样称呼它:


    GetMyFileSize(Application.ExeName)

    我想修改skamradt提供的代码,使之成为您要求的两行代码;-)


    但是我更喜欢使用skamradt编写的代码,因为它更安全。请注意,.Size是以字节为单位的,因此对于KB,请除以1024

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

    查看

    尝试将前两行包装为“Try..finally”,并将FindClose放在“finally”部分。这更可靠。为什么这比其他方法更好?Windows中不缺少句柄…很简单。句柄已经分配了,第1点,更好的是,它告诉您应用程序的大小,即使您在应用程序的数据后面附加了数据。了解这一点非常重要!我不知道为什么这是得票最多的答案。这篇文章包含了几个示例,说明了如何仅使用本机Delphi VCL命令来实现这一点。做得很好。我认为你的答案比穆罕默德·纳斯曼或我的答案更具可读性;有人能指出此代码的特定问题吗?可能是因为您没有再次释放TFileStream。
      with tFilestream.create(paramstr(0),fmOpenRead or fmShareDenyNone) do
        ShowMessage(IntToStr(size));
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      with TFileStream.Create(Application.ExeName,fmShareDenyNone) do
        ShowMessage(FloatToStr(Size/1024));
    end;
    
    uses IdGlobalProtocols;
    
    var
      ExeSize: Int64;
    begin
      ExeSize := FileSizeByName(ParamStr(0)); 
      // or
      ExeSize := FileSizeByName(Application.ExeName);
    end;