Запись двоичного файла в Inno Setup

Как записать в двоичный файл в сценарии установки Inno? Это файл конфигурации, который я хочу редактировать в PrepareToInstall шаг. Проблема в том, что я смотрю на функции поддержки:

TStream = class(TObject)
  function Read(Buffer: String; Count: Longint): Longint;
  function Write(Buffer: String; Count: Longint): Longint;
  function Seek(Offset: Longint; Origin: Word): Longint;
  procedure ReadBuffer(Buffer: String; Count: Longint);
  procedure WriteBuffer(Buffer: String; Count: Longint);
  function CopyFrom(Source: TStream; Count: Longint): Longint;
  property Position: Longint; read write;
  property Size: Longint; read write;
end;

И, кажется, даже самая простая функция записи пишет строки. Должен ли я просто сделать это в пакетном сценарии?

1 ответ

Решение

Рассмотрим string в TStream Интерфейс как буфер символов / байтов.

С Ansi-версией Inno Setup это довольно просто, поскольку один байт равен одному символу.

Это немного сложнее с версией Inno Setup для Unicode, где строка представляет собой массив 2-байтовых символов.

См. Также Считывание байтов из файла в нужной позиции с помощью Inno Setup.

Чтобы преобразовать шестнадцатеричную строку в фактические двоичные данные, вы можете использовать CryptStringToBinary Функция Windows API.

Следующий код работает как в Ansi, так и в Unicode-версии Inno Setup (вы должны использовать Unicode-версию, если это возможно).

#ifndef Unicode
const CharSize = 1;
#define AW "A"
#else
const CharSize = 2;
#define AW "W"
#endif

function CryptStringToBinary(
  sz: string; cch: LongWord; flags: LongWord; binary: string; var size: LongWord;
  skip: LongWord; flagsused: LongWord): Integer;
  external 'CryptStringToBinary{#AW}@crypt32.dll stdcall';

const
  CRYPT_STRING_HEX = $04;

procedure WriteHexToFile(Hex: string; FileName: string);
var
  Stream: TFileStream;
  Buffer: string;
  Size: LongWord;
begin
  Stream := TFileStream.Create(FileName, fmCreate);

  try
    SetLength(Buffer, (Length(Hex) div 2*CharSize) + CharSize - 1);
    Size := Length(Hex) div 2;
    if (CryptStringToBinary(
          Hex, Length(Hex), CRYPT_STRING_HEX, Buffer, Size, 0, 0) = 0) or
       (Size <> Length(Hex) div 2) then
    begin
      RaiseException('Error decoding hex string');
    end;

    Stream.WriteBuffer(Buffer, Size);
  finally
    Stream.Free;
  end;
end;

Используйте это как:

procedure WriteHexToFileTest;
var
  Hex: string;
begin
  Hex :=
    '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' + 
    '202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f' + 
    '404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f' + 
    '606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f' + 
    '808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f' + 
    'a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf' + 
    'c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf' + 
    'e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff';

  WriteHexToFile(Hex, 'my_binary_file.dat');
end;
Другие вопросы по тегам