Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to attach a resource file to an existing executable file?

I have a resource file(.RES) and i want to add it into an existing executable file without recompiling and using the IDE! is it possible?

Edit

And how to extract the resource file?

like image 990
Kermia Avatar asked May 19 '11 05:05

Kermia


People also ask

What is resource in c#?

Resources is a very useful namespace that allows you to create and store culture-specific resources used in an application (for example, you can have Spanish and English resources). Resources allows you to place culture-specific items inside satellite files, rather than directly in your main application.


3 Answers

If your question is, if you can add a resource to a existing exe file, yes it is possible. To do this you must use the UpdateResource function which can add, delete, or replace a resource in a portable executable (PE) file.

update

Here you have a sample code

{$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:\Users\Dexter\Documents\RAD Studio\Projects\Debug\Win32\Data.txt','C:\Users\Dexter\Documents\RAD Studio\Projects\Debug\Win32\project86.exe');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
like image 188
RRUZ Avatar answered Oct 12 '22 20:10

RRUZ


You can use Colin Wilson's excellent Resource Utilities.

I'm using this simple console application to add a resource to an executable using his tools:

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; { AddRes }

begin
  if ParamCount <> 2 then
    Writeln('Usage: AddResource <exe file> <resource file>')
  else
    AddRes(ParamStr(1), ParamStr(2));
end.
like image 34
gabr Avatar answered Oct 12 '22 19:10

gabr


This is my answer : (Thank you PRUZ)

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:\somebitmap.bmp', fmOpenRead);
      FS.Seek(0, soFromBeginning);
      DataLength := FS.Size;
      GetMem(Data, DataLength);
      FS.Read(Data^, DataLength);
      FS.Free;

      Ok := True;
      IF (not UpdateResource(ResourceHandle, RT_RCDATA, pChar('MyNewResource'), LANG_SYSTEM_DEFAULT{MakeLangID(LANG_NEUTRAL, SUBLANG_NEUTRAL)}, Data, DataLength)) Then Ok := False;

      IF (not EndUpdateResource(ResourceHandle, False)) Then Ok := False;

      IF (Ok) Then ShowMessage('Update of resources successful!')
         Else ShowMessage('Update of resources failed!');

      FreeMem(Data);
   End;
End. 

Reference : http://www.delphi3000.com

like image 4
Kermia Avatar answered Oct 12 '22 18:10

Kermia