从EXE中提取文件

时间:2012-10-25 17:14:27

标签: delphi embedded-resource

我想从我的EXE中提取一个没有扩展名的文件myfile

如果我使用“Resource Builder”创建资源文件Resource.res并将其添加到我的项目{$R Resource.res},我可以这样做。

我正在使用此代码

implementation

{$R *.dfm}
{$R Resource.res}

procedure TForm1.Button1Click(Sender: TObject);
var
  fname :string;
  rStream : TResourceStream;
begin
  fname := 'myfile';
  rStream := TResourceStream.Create(hInstance, 'FILE1', RT_RCDATA) ;
  try
    rStream.SaveToFile(ExtractFilePath(ParamStr(0))+fname);
  finally
    rStream.Free
  end;
end;

如果我使用“资源和图像...”将没有扩展名的文件添加到我的项目中,我收到错误:“找不到资源FILE1”

如何使用第二种方法提取myfile

1 个答案:

答案 0 :(得分:0)

您可以做的是将文件保存为程序中的字节(不是资源)。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ComCtrls,
  Types;

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    BitBtn1: TBitBtn;
    Button1: TButton;
    procedure BitBtn1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function FileToByteConst(const AFileToRead, AFileToWrite,
  AConstName: string): boolean;
var
  _InputStream: TMemoryStream;
  _OutputStream: TFileStream;
  _WriterStream: TStreamWriter;
  i: Integer;
  p: PByte;
  _Line: string;
begin
  _InputStream := TMemoryStream.Create;
  try
    _InputStream.LoadFromFile(AFileToRead);

    _OutputStream := TFileStream.Create(AFileToWrite, fmCreate);
    try
      _WriterStream := TStreamWriter.Create(_OutputStream);
      try
        _WriterStream.WriteLine('const');
        _WriterStream.WriteLine(Format('  ' + UpperCase(AConstName) +
          ': array[0..%d] of Byte = (', [_InputStream.Size - 1]));

        p := _InputStream.Memory;
        for i := 0 to _InputStream.Size - 1 do
        begin
          _Line := _Line + Format('%d, ', [p^]);
          // We don't want line to be too long
          if Length(_Line) >= 80 then
          begin
            _WriterStream.WriteLine(_Line);
            _Line := '';
          end;
          p := PByte(Integer(p) + 1);
        end;

        SetLength(_Line, Length(_Line) - 2);
        _WriterStream.WriteLine(Format('%s);', [_Line]));
        Result := true;
      finally
        FreeAndNil(_WriterStream);
      end;
    finally
      FreeAndNil(_OutputStream);
    end;
  finally
    FreeAndNil(_InputStream);
  end;
end;

function ByteArrayToFile(const AByteArray: array of byte;
  const AFileName: string): boolean;
var
  _Count, _RecordsWritten: Integer;
  F: file of byte;
  _pTemp: Pointer;
begin
  Result := false;
  AssignFile(F, AFileName);
  Rewrite(F);
  try
    _Count := Length(AByteArray);
    _pTemp := @AByteArray[0];
    BlockWrite(F, _pTemp^, _Count, _RecordsWritten);
    if _RecordsWritten <> 0 then
      Result := true;
  finally
    CloseFile(F);
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  if FileToByteConst('C:\Users\Edijus\Desktop\input.bmp',
    'C:\Users\Edijus\Desktop\const_inc.pas', 'my_array_2') then
    ShowMessage('OK')
  else
    ShowMessage('Failed to create constant array of bytes');
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  // Unicode text file
  MY_ARRAY: array [0 .. 57] of byte = (255, 254, 108, 0, 97, 0, 98, 0, 97, 0,
    115, 0, 13, 0, 10, 0, 5, 1, 13, 1, 25, 1, 23, 1, 47, 1, 97, 1, 115, 1, 107,
    1, 57, 0, 48, 0, 45, 0, 126, 1, 13, 0, 10, 0, 118, 0, 97, 0, 107, 0, 97, 0,
    114, 0, 97, 0, 115, 0);
{$INCLUDE 'C:\Users\Edijus\Desktop\const_inc'}
begin
  if ByteArrayToFile(MY_ARRAY_2, 'C:\Users\Edijus\Desktop\BackToFile.bmp') then
    ShowMessage('OK')
  else
    ShowMessage('Failed to create file of bytes');
end;

end.