Легко получить размер приложения - PullRequest
7 голосов
/ 20 октября 2008

Есть ли в Delphi способ получить исполняемый размер приложения в одной или двух строках кода?

Ответы [ 9 ]

10 голосов
/ 20 октября 2008

Просто ради ухмылки ... вы можете сделать это с помощью потоков, чуть больше двух строк кода. Обычно имя файла приложения, включая путь, также сохраняется в Paramstr (0).

var
  fs : tFilestream;
begin
  fs := tFilestream.create(paramstr(0),fmOpenRead or fmShareDenyNone);
  try
    result := fs.size;
  finally
    fs.free;
  end;
end;
5 голосов
/ 20 октября 2008

Это не так мало, как вы хотите, но не требует ручек. Я использую это во всех моих "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;
4 голосов
/ 21 октября 2008

Ради будущей совместимости вы должны выбрать реализацию, которая не требует указателей или функций Windows API, когда это возможно. Решение на основе TFileStream, предоставленное skamradt, выглядит хорошо для меня.

Но ... Вы не должны слишком беспокоиться о том, содержит ли процедура 1 или 10 строк кода, потому что вы все равно собираетесь инкапсулировать ее в функцию, которая принимает имя файла в качестве параметра и возвращает Int64, поместите его в свою личную библиотеку многоразового кода. Тогда вы можете назвать это так:

GetMyFileSize (Application.ExeName);

2 голосов
/ 04 августа 2012
uses IdGlobalProtocols;

var
  ExeSize: Int64;
begin
  ExeSize := FileSizeByName(ParamStr(0)); 
  // or
  ExeSize := FileSizeByName(Application.ExeName);
end;
2 голосов
/ 20 октября 2008

Потоки также могут использоваться без переменной TFileStream:

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

Гадкий, да.

Я предпочитаю использовать DSiFileSize от DSiWin32 . Он использует 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 }
2 голосов
/ 20 октября 2008

Вы можете попробовать это:

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

===============
Neftali

2 голосов
/ 20 октября 2008

К сожалению, это невозможно сделать с помощью одной или двух строк кода без использования какой-либо библиотеки.

Самое простое - получить exe-файл приложения. Вы можете найти его в Application.ExeName

В общем, есть несколько возможностей получения размера файла:

  1. Откройте файл и прочитайте размер потока. Это можно сделать с помощью «старых» функций Delphi FileOpen и FileSize, либо с помощью TFileStream (используйте свойство size), либо с помощью функций Win32 API CreateFile и GetFileSize. (Зависит от платформы!) Убедитесь, что вы открываете файл с доступом только для чтения.
  2. В чистом окружении Win32 вы можете использовать FindFirst, чтобы получить размер файла. Вы можете прочитать это из TSearchRec.FindData.nFileSizeLow. Если вы хотите подготовиться к файлам размером более 2 ГБ (вам следует), вы должны использовать также часть nFileSizeHigh.
  3. В Delphi.NET вы можете использовать System.IO.FileInfo, например: FileInfo.Create(filename).Length (однострочный)
  4. В Linux вы можете использовать функцию lstat64 (Unit Libc) и получить размер от TStatBuf64.st_size. (двухстрочный, если не считать объявление переменной)

В библиотеке JCL вы можете найти множество полезных функций, в том числе простую функцию, которая возвращает размер файла с заданным именем файла. (Используется метод, подходящий для данной платформы)

0 голосов
/ 21 октября 2008

Самое короткое, что я мог сделать. Обратите внимание, что .Size указан в байтах, поэтому для килобайтов разделите его на 1024.

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

Проверьте эту ссылку.

0 голосов
/ 21 октября 2008

Я хотел бы изменить код, предоставленный skamradt, чтобы сделать его двумя строками кода, как вы просили; -)

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

но я бы предпочел использовать код как skamradt , потому что он более безопасен

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...