5

アンインストール ファイル (JPEG、DLL、PNG...) を .xml ファイル内に残す方法はありunins000.exeますか? もしそうなら、コードを見せてください。

4

2 に答える 2

7

これを行う方法はありません。Inno アンインストール エンジンには、埋め込みファイルを含めることはできません。

しかし一方で、そうする必要は特にありません。必要なファイルをインストールするだけで済みます (物事を整理したい場合は、アプリ フォルダーのサブフォルダーにインストールします)。

セットアップ ファイルがインストーラーに組み込まれている唯一の本当の理由は、ダウンロードを容易にするためです。アンインストーラーにはその言い訳はありません。

于 2013-02-13T11:26:07.473 に答える
4

Inno Setup には、埋め込みファイルのネイティブ サポートはありません。

ただし、創造性を働かせれば、ファイルを (何らかの定数の形で) コードに埋め込むことができます。

残念ながら、Unicode Inno Setup は、バイナリ データを扱う場合、すべてを UTF-8 に変換しようとする傾向があるため、かなり制限されています。しかし、何度も試行した後、いくつかの機能するコードになりました ( Inno Setup プリプロセッサから呼び出された PowerShell コードを使用して)。


このコードを[Code]セクションの先頭に追加します。

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

const
  CRYPT_STRING_HEX = $04;

procedure WriteBinaryStringToStream(S: string; Stream: TStream);
var
  Buffer: string;
  Size: LongWord;
begin
  SetLength(Buffer, (Length(S) div 4) + 1);
  Size := Length(S) div 2;
  if (CryptStringToBinary(S, Length(S), CRYPT_STRING_HEX, Buffer, Size, 0, 0) = 0) or
     (Size <> Length(S) div 2) then
  begin
    RaiseException('Error decoding binary string');
  end;

  Stream.WriteBuffer(Buffer, Size);
end;  

function StreamFromBinaryString(S: string): TStream;
begin
  Result := TStringStream.Create('');
  WriteBinaryStringToStream(S, Result);
  Result.Position := 0;
end;

procedure LoadBitmapFromBinaryString(Bitmap: TBitmap; S: string);
var
  Stream: TStream;
begin
  Stream := StreamFromBinaryString(S);
  try
    Bitmap.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

procedure SaveBinaryStringToFile(FileName: string; S: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmCreate);
  try
    WriteBinaryStringToStream(S, Stream);
  finally
    Stream.Free;
  end;
end;

#define FileToBinaryString(str FileName) \
  Local[4] = ExtractFileName(FileName), \
  Local[0] = AddBackslash(GetEnv("TEMP")) + Local[4] + ".pas", \
  Local[1] = \
    "-ExecutionPolicy Bypass -Command """ + \
    "Write-Host 'Generating code for " + Local[4] + "'; " + \
    "$bytes = [System.IO.File]::ReadAllBytes('" + FileName + "'); " + \
    "$s = '''' + (($bytes | foreach { $_.ToString('X2') }) -join '') + ''''; " + \
    "Set-Content -Path '" + Local[0] + "' -Value $s;" + \
    """", \
  Exec("powershell.exe", Local[1], SourcePath, , SW_HIDE), \
  Local[2] = FileOpen(Local[0]), \
  Local[3] = FileRead(Local[2]), \
  FileClose(Local[2]), \
  DeleteFileNow(Local[0]), \
  Local[3]

次に、FileToBinaryString プリプロセッサ マクロを使用して、コンパイル時 (より正確には前処理時) にファイルを次のような 16 進文字列に変換できます。

'4D5A50000200000004000F00FFFF0000B8000....'

実行時に、関数WriteBinaryStringToStreamStreamFromBinaryStringLoadBitmapFromBinaryStringまたはの一部で 16 進文字列を使用しますSaveBinaryStringToFile


たとえば、ビットマップを にロードするにはTBitmapImage、次を使用します。

LoadBitmapFromBinaryString(
  BitmapImage.Bitmap, {#FileToBinaryString("C:\path\WizModernSmallImage.bmp")});

コンパイル時に、これは次のようなコードに変換されます。

LoadBitmapFromBinaryString(
  BitmapImage.Bitmap, '4D5A50000200000004000F00FFFF0000B8000....');

DLL を抽出するには、次を使用します。

SaveBinaryStringToFile(
  ExpandConstant('{tmp}\InnoCallback.dll'), {#FileToBinaryString("InnoCallback.dll")});

実行時に抽出された DLL を使用するには、次のdelayloadフラグを使用する必要があります。

function WrapTimerProc(callback:TTimerProc; paramcount:integer):longword;
  external 'wrapcallback@{tmp}\innocallback.dll stdcall delayload';

プリプロセッサ/Pascal コンパイラには、文字列に対して約 1 億文字の制限があります。ただし、実際には、約 20 ~ 30 MB を超えるファイルの場合、最初に PowerShell スクリプトの [コンパイル時の] メモリ制限に達します。サイズが小さい (数 MB より大きい) 場合でも、PowerShell スクリプトのコンパイル時のパフォーマンスは良くありません。ただし、スクリプトは大幅に最適化できます。

16 進エンコーディングのため、インストーラーのサイズは 2 倍になります。これは、Base64 ( ) などのより効率的なエンコーディングを使用することで改善される可能性がありますCRYPT_STRING_BASE64。セクションに含まれるファイルと比較して、コード セクションも圧縮されてい[Files]ません (これらは既に圧縮されているため、画像の問題ではありませんが、たとえば DLL では違いが生じます)。


このソリューションは、当初、 Inno Setup: Reading a file from installer during uninstallingという質問に対して開発されました


コードには Inno Setup の Unicode バージョンが必要です。最新の Inno Setup 6 では、これが利用可能な唯一のバージョンです。Inno Setup 5 を使用していても、21 世紀の Ansi バージョンは使用しないでください。皮肉なことに、これを Ansi バージョンに実装する方がはるかに簡単です。Ansi と Unicode の両方のバージョンの Inno Setup と互換性のある の使用については、Inno Setup でのバイナリ ファイルの書き込みに対する私の回答を参照してください。CryptStringToBinaryAnsi バージョンでは、実際には 16 進文字列の代わりにバイナリ文字列を使用できます。

于 2016-07-12T18:54:28.107 に答える