2016-07-27 4 views
2

Inno Setup 스크립트에서 바이너리 파일에 어떻게 쓰는지? 이 파일은 PrepareToInstall 단계에서 수정하려는 구성 파일입니다.Inno Setup에서 바이너리 파일 쓰기

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; 

을 그리고 심지어 가장 기본적인 쓰기 기능은 문자열을 쓰는 것 같다 문제는 내가 지원 기능에서 찾고 있다는 점이다. 배치 스크립트로해야할까요?

+0

내 텍스트 편집기 진수로 열고, 그것은 이진 파일입니다 생각합니다. UTF-8 인코딩으로 열면 텍스트가 있지만 NUL, SOH, ETX 문자 등이 잔뜩 있습니다. –

답변

2

TStream 인터페이스의 string을 문자/바이트 버퍼로 간주하십시오.

Inno Setup의 Ansi 버전을 사용하면 1 바이트가 1 자로 동일하므로 매우 쉽습니다.

Inno Setup 유니 코드 버전의 경우 문자열이 2 바이트 문자 배열 인 경우 조금 더 복잡합니다.

도 참조하십시오. Read bytes from file at desired position with Inno Setup.

16 진수 문자열을 실제 이진 데이터로 변환하려면 CryptStringToBinary Windows API function을 사용할 수 있습니다.

다음 코드는 Ansi 및 Unicode 버전의 Inno 설치에서 작동합니다 (가능한 경우 유니 코드 버전을 사용해야합니다).

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

http://www.jrsoftware.org/ishelp/index.php?topic=unicode에 따르면, 유니 코드가 아닌 버전이 실행 중입니다. –

+0

그래, 내 대답은 도움이 되나요? 아니면 자세한 내용이 필요합니까? (어떤 경우에, 우리는 또한 당신에게서 더 많은 세부 사항을 필요로한다). –

+0

필자의 어려움은'procedure WriteBuffer (Buffer : String; Count : Longint);와'function Write (Buffer : String; Count : Longint) : Longint' 둘 다 String을 취하는 것처럼 보입니다. 그러나 온라인에서 찾은 대답은이를 무시하는 것처럼 보입니다. 이제 Innoscript가 매우 제한된 델파이 세트를 사용하는지 궁금합니다 (처음에는 HexToBin이 없으므로 신의 선물이 될 것입니다). 어쨌든, 지금 당장 나는 문법 오류에 당황 스럽다. [여기] (http://stackoverflow.com/questions/38621801/what-is-the-syntax-error-in-this- inno-script). –