如何将资源文件附加到现有的可执行文件?

时间:2011-05-19 05:42:17

标签: delphi resources

我有一个资源文件(.RES),我想将它添加到现有的可执行文件中,而无需重新编译和使用IDE!有可能吗?

修改

如何提取资源文件?

3 个答案:

答案 0 :(得分:10)

如果您的问题是,如果您可以将资源添加到现有的exe文件,是的,这是可能的。为此,您必须使用可以add, delete, or replace a resource in a portable executable (PE) file的{​​{3}}功能。

<强>更新

这里有一个示例代码

{$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.

答案 1 :(得分:6)

你可以使用Colin Wilson的优秀Resource Utilities

我正在使用这个简单的控制台应用程序使用他的工具向可执行文件添加资源:

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.

答案 2 :(得分:4)

这是我的答案:(谢谢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. 

参考:http://www.delphi3000.com