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

Inno setup 如何将卸载文件保存在卸载程序中?,inno-setup,Inno Setup,有没有办法让卸载文件(JPEG、DLL、PNG…)留在unins000.exe中?如果是,请显示代码。没有任何方法可以做到这一点。Inno卸载引擎不能包含嵌入文件 但另一方面,它也没有特别需要这样做——你只需安装它所需要的任何文件(如果你想保持整洁,可以安装到app文件夹的子文件夹中) 将安装文件嵌入安装程序的唯一真正原因是它使下载更容易。卸载程序没有这个借口。Inno安装程序不支持嵌入文件 但是,通过一些创造性,您可以将文件嵌入到代码中(以某种常量的形式) 不幸的是,Unicode Inno设

有没有办法让卸载文件(JPEG、DLL、PNG…)留在
unins000.exe
中?如果是,请显示代码。

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

但另一方面,它也没有特别需要这样做——你只需安装它所需要的任何文件(如果你想保持整洁,可以安装到app文件夹的子文件夹中)


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

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

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

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


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

函数CryptStringToBinary(
sz:string;cch:LongWord;标志:LongWord;二进制:string;变量大小:LongWord;
跳过:长单词;标记使用:长单词):整数;
外部的CryptStringToBinaryW@crypt32.dllstdcall';
常数
密码字符串十六进制=$04;
过程WriteBinaryStringToStream(S:string;Stream:TStream);
变量
缓冲区:字符串;
大小:长字;
开始
SetLength(缓冲区)(长度(S)第4部分)+1);
尺寸:=第2部分的长度;
如果(CryptStringToBinary(S,长度,CRYPT_字符串,十六进制,缓冲区,大小,0,0)=0)或
(尺寸长度第2部分)然后
开始
RaiseException('Error decoding binary string');
结束;
Stream.WriteBuffer(缓冲区,大小);
结束;
函数StreamFromBinaryString(S:string):TStream;
开始
结果:=TStringStream.Create(“”);
WriteBinaryStringToStream(S,结果);
结果.位置:=0;
结束;
过程LoadBitmapFromBinaryString(位图:TBitmap;S:string);
变量
溪流:尖沙咀;;
开始
Stream:=StreamFromBinaryString;
尝试
LoadFromStream(Stream);
最后
免费;
结束;
结束;
过程SaveBinaryStringToFile(文件名:string;S:string);
变量
溪流:尖沙咀;;
开始
Stream:=TFileStream.Create(文件名,fmCreate);
尝试
WriteBinaryStringToStream(S,Stream);
最后
免费;
结束;
结束;
#定义FileToBinaryString(str文件名)\
本地[4]=提取文件名(文件名)\
本地[0]=AddBackslash(GetEnv(“TEMP”))+Local[4]+“.pas”\
本地[1]=\
-ExecutionPolicy旁路-命令“”+\
“写入主机”生成“+Local[4]+”;“+\
“$bytes=[System.IO.File]::ReadAllBytes(“+FileName+”);”+\
“$s=''”+($bytes | foreach{$\ ToString('X2')})-连接“”)+''”;”+\
“设置内容-路径”“+Local[0]+”'-值$s;“+\
"""", \
Exec(“powershell.exe”、本地[1]、源路径、软件隐藏)\
本地[2]=文件打开(本地[0])\
本地[3]=文件读取(本地[2])\
FileClose(本地[2])\
DeleteFileNow(本地[0])\
本地[3]

然后可以使用
filetobinarysting
在编译时(或者更准确地说,在预处理时)将文件转换为十六进制字符串,如:

“4D5A50000200004000F00FF0000B8000…”
在运行时,将十六进制字符串与一些函数一起使用
WriteBinaryStringToStream
StreamFromBinaryString
LoadBitmapFromBinaryString
SaveBinaryStringToFile


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

LoadBitmapFromBinaryString(
位图,{#FileToBinaryString(“C:\path\WizModernSmallImage.bmp”)};
在编译时,会将其转换为如下代码:

LoadBitmapFromBinaryString(
位图“4D5A50000200004000F00FFFF0000B8000…”;

要提取DLL,请使用:

SaveBinaryStringToFile(
ExpandConstant({tmp}\InnoCallback.dll'),{filetobinarysting(“InnoCallback.dll”)};
要使用在运行时提取的DLL,必须使用:

函数WrapTimerProc(回调:TTimerProc;paramcount:integer):长单词;
外部'wrapcallback@{tmp}\innocallback.dll stdcall delayload';

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

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


这个解决方案最初是针对这个问题开发的



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

这更适合@boj吗?不,这是一个开发问题。嗨,米拉尔。谢谢您的帮助。实际上,通过一些创造性,有一种方法。是的,但这样做的努力通常超过了好处。只安装文件更简单。尽管如此,f点