Иногда разработчикам может потребоваться добавить ресурсный файл в существующий исполняемый файл без необходимости перекомпиляции проекта. В этой статье мы рассмотрим, как это можно сделать, используя возможности операционной системы и сторонние инструменты.
Проблема
Разработчик обладает ресурсным файлом (.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
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.