Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Извлечение и Добавление Ресурсов в Экзешники Delphi без Перекомпиляции

Delphi , Файловая система , Ресурсы

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

Проблема

Разработчик обладает ресурсным файлом (.RES) и хочет добавить его в уже скомпилированный исполняемый файл без использования IDE и без перекомпиляции проекта. Возможен ли такой сценарий?

Решение

Добавление ресурса в существующий исполняемый файл

Для добавления ресурса в существующий исполняемый файл можно использовать функцию UpdateResource, которая позволяет добавлять, удалять или заменять ресурсы в портативном исполняемом файле (PE). В контексте Delphi и Object Pascal, это можно сделать с помощью следующего кода:

{$APPTYPE CONSOLE}

uses
  Classes,
  Windows,
  SysUtils;

procedure UpdateExeResource(Const Source, Dest: string);
var
  Stream: TFileStream;
  hDestRes: THANDLE;
  lpData: Pointer;
  cbData: DWORD;
begin
  Stream := TFileStream.Create(Source, fmOpenRead or fmShareDenyNone);
  try
    Stream.Seek(0, soFromBeginning);
    cbData := Stream.Size;
    if cbData > 0 then
    begin
      GetMem(lpData, cbData);
      try
        Stream.Read(lpData^, cbData);
        hDestRes := BeginUpdateResource(PChar(Dest), False);
        if hDestRes <> 0 then
          if UpdateResource(hDestRes, RT_RCDATA, 'DATA', 0, lpData, cbData) then
          begin
            if not EndUpdateResource(hDestRes, FALSE) then
              RaiseLastOSError
          end
          else
            RaiseLastOSError;
        else
          RaiseLastOSError;
      finally
        FreeMem(lpData);
      end;
    end;
  finally
    Stream.Free;
  end;
end;

begin
  try
    UpdateExeResource('C:\path\to\resource.txt', 'C:\path\to\your\existing\exe.exe');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Альтернативные инструменты

Также можно использовать утилиты от Colin Wilson, которые предоставляют более удобные возможности для работы с ресурсами:

program AddResource;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  Classes,
  unitNtModule,
  unitResFile,
  unitResourceRCData;

procedure AddRes(exeName, resName: string);
var
  exeModule: TNTModule;
  resFile: TResModule;
begin
  if ExtractFileExt(exeName) = '' then
    exeName := ChangeFileExt(exeName, '.exe');
  exeModule := TNTModule.Create;
  try
    exeModule.LoadFromFile(exeName);
    resFile := TResModule.Create;
    resFile.LoadFromFile(resName);
    exeModule.AddResource(resFile.ResourceDetails[0]);
    exeModule.SaveToFile(exeName);
  finally
    FreeAndNil(exeModule);
  end;
end;

begin
  if ParamCount <> 2 then
    Writeln('Usage: AddResource <exe file> <resource file>')
  else
    AddRes(ParamStr(1), ParamStr(2));
end.

Извлечение ресурсов из исполняемого файла

Для извлечения ресурсов можно использовать следующий код:

uses Classes, Windows, SysUtils, Dialogs;

Type
  TBuffer = Array[0..0] of Byte;
  PBuffer = ^TBuffer;

var
  FS: TFileStream;
  ResourceHandle: THandle;
  DataLength: DWord;
  Data: PBuffer;
  Ok: Boolean;

begin
  ResourceHandle := BeginUpdateResource(PChar('d:\someexefile.exe'), False);
  if (ResourceHandle <> 0) then
  begin
    FS := TFileStream.Create('d:\resource.bmp', fmCreate);
    try
      if FindResource(ResourceHandle, pChar('MyNewResource'), RT_RCDATA) <> 0 then
      begin
        DataLength := SizeofResource(ResourceHandle, pChar('MyNewResource'));
        GetMem(Data, DataLength);
        if not ExtractResource(ResourceHandle, pChar('MyNewResource'), RT_RCDATA, Data^, @DataLength) then
          RaiseLastOSError;
        FS.Write(Data^, DataLength);
        FS.Commit(0);
      end;
    finally
      FS.Free;
    end;
    if not EndUpdateResource(ResourceHandle, False) then RaiseLastOSError;
    FreeMem(Data);
  end;
end.

Заключение

Добавление и извлечение ресурсов в исполняемые файлы без перекомпиляции — задача, которая может потребоваться в различных ситуациях, например, при обновлении версии программы или при внесении мелких исправлений. Использование функций операционной системы, а также сторонних инструментов, позволяет разработчикам решать такие задачи с минимальными усилиями и затратами времени.

Создано по материалам из источника по ссылке.

Инструкция по извлечению и добавлению ресурсов в исполняемые файлы Delphi без перекомпиляции.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Ресурсы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 12:17:09/0.0035760402679443/0