首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将卸载文件保存在卸载程序中?

如何将卸载文件保存在卸载程序中?
EN

Stack Overflow用户
提问于 2013-02-13 13:49:20
回答 2查看 609关注 0票数 5

有任何方法来制作卸载文件(JPEG,DLL,PNG...)留在unins000.exe内部?如果是,请显示代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-13 19:26:07

没有任何方法可以做到这一点。Inno卸载引擎不能包含嵌入文件。

但另一方面,它也不需要这样做--您只需安装它所需的任何文件(如果您想保持整洁,可以将其安装到app文件夹的子文件夹中)。

安装文件嵌入到安装程序中的唯一真正原因是它使下载变得更容易。卸载程序没有这样的借口。

票数 7
EN

Stack Overflow用户

发布于 2016-07-13 02:54:28

Inno安装程序不支持嵌入文件。

但是通过一些创造性,您可以将文件嵌入到代码中(以某种常量的形式)。

不幸的是,Unicode Inno设置在处理二进制数据时非常有限,因为它倾向于尝试将所有内容转换为UTF-8。但是经过多次尝试,我最终得到了一些可以工作的代码(使用从Inno Setup preprocessor调用的PowerShell代码)。

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

代码语言:javascript
复制
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 preprocessor macro在编译时(或者更准确地说,在预处理时)将文件转换为如下所示的十六进制字符串:

代码语言:javascript
复制
'4D5A50000200000004000F00FFFF0000B8000....'

在运行时,您可以将十六进制字符串与一些函数WriteBinaryStringToStreamStreamFromBinaryStringLoadBitmapFromBinaryStringSaveBinaryStringToFile一起使用。

因此,例如,要将位图加载到TBitmapImage,请使用:

代码语言:javascript
复制
LoadBitmapFromBinaryString(
  BitmapImage.Bitmap, {#FileToBinaryString("C:\path\WizModernSmallImage.bmp")});

在编译时,这将转换为如下代码:

代码语言:javascript
复制
LoadBitmapFromBinaryString(
  BitmapImage.Bitmap, '4D5A50000200000004000F00FFFF0000B8000....');

要提取DLL,请使用:

代码语言:javascript
复制
SaveBinaryStringToFile(
  ExpandConstant('{tmp}\InnoCallback.dll'), {#FileToBinaryString("InnoCallback.dll")});

要使用在运行时提取的DLL,必须使用delayload flag

代码语言:javascript
复制
function WrapTimerProc(callback:TTimerProc; paramcount:integer):longword;
  external 'wrapcallback@{tmp}\innocallback.dll stdcall delayload';

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

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

这个解决方案最初是为问题开发的。

该代码需要Inno安装程序的Unicode版本。使用最新的Inno Setup 6,它是唯一可用的版本。在21世纪,即使你使用Inno Setup 5,你也不应该使用Ansi版本。不过具有讽刺意味的是,在Ansi版本中实现这一点要容易得多。有关与Inno安装程序的Ansi和Unicode版本兼容的CryptStringToBinary的用法,请参阅。虽然在Ansi版本中,您实际上可以使用二进制字符串,而不是十六进制字符串。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14847218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档