Inno Setup:在卸载过程中从安装程序读取文件

小牛

卸载期间使用以下代码

BitmapImage := TBitmapImage.Create(InstallTopPanel);
BitmapImage.AutoSize := True;
BitmapImage.Bitmap.LoadFromFile(ExpandConstant( '{tmp}\WizardSmallImageFile.bmp') );
BitmapImage.Parent := InstallTopPanel;
BitmapImage.Top := (InstallTopPanel.ClientHeight - 58) / 2;
BitmapImage.Left := InstallTopPanel.ClientWidth - 55 - 10;

我收到一个错误:

异常:无法打开文件。C:\ users \ xyz \ AppData \ Local \ Temp \ is-U3Q8P.tmp \ WizardSmallImageFile.Bmp。文件未找到。

我也尝试ExtractTemporaryFile在致电之前使用LoadFromFile它,这在卸载期间不受支持。

ExtractTemporaryFile('WizardSmallImageFile.bmp');

那么,问题是,如何查看图像,或者特别是WizardSmallImageFile在卸载过程中?

马丁·普里克里(Martin Prikryl)

正确,ExtractTemporaryFile从安装程序中提取文件。因此,由于安装程序不再可用,因此无法在卸载程序中使用。

还要注意,无论如何您都无法从安装程序中提取WizardSmallImageFile指令所引用的文件您必须添加自己的副本。


如果需要在卸载过程中使用某些文件,则必须将其安装在安装程序中,然后在卸载程序中使用已安装的副本。

[Files]
Source: "WizardSmallImageFile.bmp"; DestDir: "{app}";

[Code]

function InitializeUninstall(): Boolean;
begin
  ...
  BitmapImage := TBitmapImage.Create(...);
  ...
  BitmapImage.Bitmap.LoadFromFile(ExpandConstant('{app}\WizardSmallImageFile.bmp'));
  ...
end;

如果您不想安装文件就可以将图像数据嵌入到代码中。

不幸的是,在处理二进制数据时,Unicode Inno Setup非常有限,因为它倾向于尝试将所有内容转换为UTF-8。但是经过无数次尝试,我最终得到了一些有效的代码。

请注意,该代码使用从Inno Setup预处理程序调用的PowerShell代码-仅在编译时才需要PowerShell,而在运行/安装时则不需要。

将此代码添加到您的[Code]部分的前面

function CryptStringToBinary(
  sz: string; cch: LongWord; flags: LongWord; binary: string; var size: LongWord;
  skip: LongWord; flagsused: LongWord): Integer;
  external '[email protected] 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 预处理器宏在编译时(或更准确地说,在预处理时)将文件转换为十六进制字符串,例如:

'4D5A50000200000004000F00FFFF0000B800000....'

在运行时,您可以使用十六进制字符串的一些功能WriteBinaryStringToStreamStreamFromBinaryStringLoadBitmapFromBinaryStringSaveBinaryStringToFile

在您的情况下,您将使用:

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

在编译时,这将转换为类似以下的代码:

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

预处理器/ Pascal编译器的字符串限制为大约100M个字符。尽管实际上,对于大于约20-30 MB的文件,您实际上会首先达到PowerShell脚本的[编译时]内存限制。尽管即使是较小的大小(大于几个MB),PowerShell脚本的编译时性能也很差。不过,该脚本可以进行显着优化。

由于十六进制编码,安装程序的大小增加了两倍。这可以通过使用一些更有效的编码来改善,例如Base64(CRYPT_STRING_BASE64)。与该[Files]节中包含的文件相比,代码节甚至都没有被压缩(图像已经压缩,这对图像来说不是问题,但是与DLL有所不同)。

该代码需要Inno Setup的Unicode版本。无论如何,在21世纪,您都不应使用Ansi版本。尽管具有讽刺意味的是,在Ansi版本中实施此操作会更容易。请参阅我对在Inno Setup中编写二进制文件的回答,以了解CryptStringToBinary与Ansi和Unicode版本的Inno Setup兼容的用法尽管在Ansi版本中,您实际上可以使用二进制字符串而不是十六进制字符串。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Inno Setup:在卸载过程中重新启动后删除文件夹

来自分类Dev

Inno Setup:加载在安装过程中为wpInfoAfter编辑的文件

来自分类Dev

Inno Setup:加载在安装过程中为wpInfoAfter编辑的文件

来自分类Dev

Inno安装程序在安装过程中执行大的sql脚本文件

来自分类Dev

通过Inno Setup创建的安装程序无法在Windows 10上的安装过程中关闭应用程序

来自分类Dev

卸载程序中的Inno Setup脚本常量

来自分类Dev

使用inno-setup在安装过程中显示文本

来自分类Dev

Inno Setup:在安装过程中重新启动不会在重启后开始

来自分类Dev

在Inno Setup的安装过程中写入Node app .js配置

来自分类Dev

如何使用Inno Setup安装程序和卸载程序删除某些文件

来自分类Dev

在安装后续过程中,Inno安装程序将执行[UninstallRun]

来自分类Dev

强制Inno安装程序在安装过程中显示UAC提示

来自分类Dev

Inno Setup:在设置过程中重新启动

来自分类Dev

Inno Setup-如何在设置过程中从文本文件编辑特定行?

来自分类Dev

在静默安装过程中,Inno Setup将锁定的文件替换为下一次重新启动

来自分类Dev

在Inno Setup中取消安装

来自分类Dev

Inno Setup:如果程序文件夹中存在文件,则关闭安装程序向导

来自分类Dev

根据在线文件设置Inno Setup安装程序版本

来自分类Dev

Inno Setup - 避免显示子安装程序的文件名

来自分类Dev

Inno Setup中的TTreeView

来自分类Dev

从Inno Setup中的临时文件夹安装包含的安装程序

来自分类Dev

在Inno Setup中从过程调用函数?

来自分类Dev

在Inno Setup中加载用于卸载过程的外部DLL

来自分类Dev

在Inno Setup中加载用于卸载过程的外部DLL

来自分类Dev

使用Inno Setup创建透明的安装程序?

来自分类Dev

Inno Setup:尝试卸载时检测安装程序是否正在运行

来自分类Dev

如何从Inno Setup安装JRE?

来自分类Dev

Inno Setup卸载程序在哪里可执行?

来自分类Dev

Inno Setup 6.0.5始终创建没有签名的新卸载程序文件

Related 相关文章

  1. 1

    Inno Setup:在卸载过程中重新启动后删除文件夹

  2. 2

    Inno Setup:加载在安装过程中为wpInfoAfter编辑的文件

  3. 3

    Inno Setup:加载在安装过程中为wpInfoAfter编辑的文件

  4. 4

    Inno安装程序在安装过程中执行大的sql脚本文件

  5. 5

    通过Inno Setup创建的安装程序无法在Windows 10上的安装过程中关闭应用程序

  6. 6

    卸载程序中的Inno Setup脚本常量

  7. 7

    使用inno-setup在安装过程中显示文本

  8. 8

    Inno Setup:在安装过程中重新启动不会在重启后开始

  9. 9

    在Inno Setup的安装过程中写入Node app .js配置

  10. 10

    如何使用Inno Setup安装程序和卸载程序删除某些文件

  11. 11

    在安装后续过程中,Inno安装程序将执行[UninstallRun]

  12. 12

    强制Inno安装程序在安装过程中显示UAC提示

  13. 13

    Inno Setup:在设置过程中重新启动

  14. 14

    Inno Setup-如何在设置过程中从文本文件编辑特定行?

  15. 15

    在静默安装过程中,Inno Setup将锁定的文件替换为下一次重新启动

  16. 16

    在Inno Setup中取消安装

  17. 17

    Inno Setup:如果程序文件夹中存在文件,则关闭安装程序向导

  18. 18

    根据在线文件设置Inno Setup安装程序版本

  19. 19

    Inno Setup - 避免显示子安装程序的文件名

  20. 20

    Inno Setup中的TTreeView

  21. 21

    从Inno Setup中的临时文件夹安装包含的安装程序

  22. 22

    在Inno Setup中从过程调用函数?

  23. 23

    在Inno Setup中加载用于卸载过程的外部DLL

  24. 24

    在Inno Setup中加载用于卸载过程的外部DLL

  25. 25

    使用Inno Setup创建透明的安装程序?

  26. 26

    Inno Setup:尝试卸载时检测安装程序是否正在运行

  27. 27

    如何从Inno Setup安装JRE?

  28. 28

    Inno Setup卸载程序在哪里可执行?

  29. 29

    Inno Setup 6.0.5始终创建没有签名的新卸载程序文件

热门标签

归档