2016-07-27 19 views
2

Wie schreibt man in Inno-Setup-Skript in eine Binärdatei? Es ist eine Konfigurationsdatei, die ich im Schritt PrepareToInstall bearbeiten möchte. Das Problem ist, dass ich an den Support-Funktionen freu:Binärdatei in Inno-Setup schreiben

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; 

Und es scheint, selbst die grundlegendsten Schreibfunktion Strings schreibt. Soll ich es nur in einem Batch-Skript tun?

+0

Ich glaube, es ist eine binäre Datei, mein Texteditor öffnet es als Hex. Wenn ich mit UTF-8-Codierung öffne, gibt es Text, aber auch eine Reihe von NUL-, SOH-, ETX-Zeichen und so weiter. –

Antwort

2

Betrachten Sie die string in der TStream Schnittstelle als Puffer von Zeichen/Bytes.

Mit Ansi-Version von Inno-Setup ist es ziemlich einfach, da dort ein Byte einem Zeichen entspricht.

Es ist etwas komplizierter mit Unicode-Version von Inno-Setup, wo die Zeichenfolge ein Array von 2-Byte-Zeichen ist.

Siehe auch Read bytes from file at desired position with Inno Setup.

Um eine Hex-Zeichenfolge in die tatsächlichen binären Daten zu konvertieren, können Sie die CryptStringToBinary Windows API function verwenden.

Der folgende Code funktioniert sowohl in Ansi-und Unicode-Version von Inno-Setup (Sie sollten die Unicode-Version verwenden, wenn möglich).

#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; 

verwenden Sie es wie:

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

    WriteHexToFile(Hex, 'my_binary_file.dat'); 
end; 
+0

Laut http://www.jrsoftware.org/ishelp/index.php?topic=unicode, verwende ich die Nicht-Unicode-Version. –

+0

OK, also funktioniert meine Antworthilfe oder benötigen Sie weitere Informationen? (In diesem Fall benötigen wir auch weitere Details von Ihnen). –

+0

Mein Problem liegt darin, dass 'procedure WriteBuffer (Buffer: String; Count: Longint);' und 'function Write (Buffer: String; Count: Longint): Longint' beide so aussehen, als würden sie nur Strings nehmen. Antworten, die ich online finde, scheinen das jedoch zu ignorieren. Jetzt frage ich mich, ob Innoscript eine sehr zurückhaltende Reihe von Delphi verwendet (für Anfänger hat es HexToBin nicht, was ein Glücksfall wäre). Jedenfalls stecke ich gerade auf einem verwirrenden Syntaxfehler, den ich [hier] gestellt habe (http://stackoverflow.com/questions/38621801/what-is-the-syntax-error-in-this- Inno-Skript). –