2006. április 1., szombat

How to embed binary data in an executable (3)


Problem/Question/Abstract:

Does anyone have experience using Delphi to create program that can create standalone exe that contains code and data like Picture2exe? This program creates a stand alone executable exe file that contains image and sound data that plays them in a slideshow. What is the approach and techniques used?

Answer:

Try this code where discclone.res includes the file you want to include:

procedure TMain.mnuCreateClick(Sender: TObject);
var
  MyFile: TFileStream;
  MyAppend: TMemoryStream;
begin
  if diagOpenSelf.Execute then
  begin
    if diagCreateSelf.Execute then
    begin
      CopyFile(PChar(ExtractFilePath(ParamStr(0)) + '\Extractor.exe'),
        PChar(diagCreateSelf.FileName), False);
      {Create a filestream object for the extractor executable}
      MyFile := TFileStream.Create(diagCreateSelf.FileName, $0002);
      try
        MyAppend := TMemoryStream.Create;
        try
          MyAppend.LoadFromFile(diagOpenSelf.FileName);
          MyFile.Seek(0, soFromEnd);
          MyFile.CopyFrom(MyAppend, 0);
          MessageBox(0, 'File was successfully created.', 'File Created',
            MB_OK + MB_ICONINFORMATION);
        finally
          MyAppend.Free;
        end;
      finally
        MyFile.Free;
      end;
    end;
  end;
end;

program Extractor;

{$R DiscClone.res}

uses
  Windows, Classes, ShellAPI, Sysutils;

const
  FileSize = 64512;
  {Or 60416. You may have to change to this number to the size of the
        compiled Extractor executable - minus the appended executable of course.}
var
  {MyExtract: TFileStream;}
  MyFile: TMemoryStream;
  TempStream: TMemoryStream;
  FileExe: string;
  Buffer: array[0..260] of Char;
  Count: DWord;
  Buf: Pointer;
  G: THandle;
  Res: LongBool;
begin
  { ... }
  {ask to make sure}
  { ... }
  {check floppy in drive}
  { ... }
  TempStream := TMemoryStream.Create;
  {Create the memory stream which will hold a copy of this executable in memory}
  MyFile := TMemoryStream.Create;
  try
    SetString(FileExe, Buffer, GetModuleFileName(0, Buffer,
      SizeOf(Buffer))); {What is the name of this executable?}
    MyFile.LoadFromFile(FileExe); {Load a copy of the executable into memory}
    {A filestream which will eventually create the HelloWorld program}
    // MyExtract := TFileStream.Create('dummy.floppy', fmCreate);
    try
      MyFile.Seek(FileSize, 0);
      Move the stream pointer to the start of the appended executable}
        {Copy the appended data to our filestream buffer - this creates the file}
    // MyExtract.CopyFrom(MyFile, MyFile.Size - FileSize);
      TempStream.CopyFrom(MyFile, MyFile.Size - FileSize);
    finally
      //  MyExtract.Free;  {Free the filestream object}
    end;
    {Tell the user that extraction went well and ask to run HelloWorld}
    G := CreateFile('\\.\A:', GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL, 0);
    //  F := CreateFile(PChar('\\.\' + location), GENERIC_READ or GENERIC_WRITE,
                0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    GetMem(Buf,1457664);  {1457664}
    //  SetFilePointer(F, 0, nil, FILE_BEGIN);
    //  ReadFile(F, Buf^, 1457664, Count, nil);
    //  Buf:=@MyExtract; //new
    WriteFile(G, Pointer(TempStream)^, 1457664, Count, nil);
    //  WriteFile(G, Buf^, 1457664, Count, nil);
    //  ShowMessage(IntToStr(GetLastError));
    FreeMem(Buf);
    //  CloseHandle(F);
    CloseHandle(G);
    
      {  G := CreateFile(PChar('\\.\C:\Work\Boot\TestCenter\Fred.txt'),
                                GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_ALWAYS,
                                FILE_ATTRIBUTE_NORMAL, 0);}
    G := CreateFile('\\.\A:', GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL, 0);
    GetMem(Buf, 1474560);
    TempStream.Position := 0;
    TempStream.Read(Buf^, 1474560);
    res := WriteFile(G, Buf^, 1474560, Count, nil);
    if not res then
      MessageBox(0, PChar(IntToStr(GetLastError)),
        PChar(SysErrorMessage(GetLastError)),
        MB_OK);
    CloseHandle(G);
    FreeMem(Buf);
    //  FlushFileBuffers(MyFileStream.Handle);
    MessageBox(0, PChar(IntToStr(TempStream.size)), 'Extraction successful!',
      MB_OK + MB_ICONQUESTION)
  finally
    {Free the memoerystream object}
    MyFile.Free;
  end;
  TempStream.Free;
end.

Nincsenek megjegyzések:

Megjegyzés küldése