Installation 使用Inno设置创建硬链接

Installation 使用Inno设置创建硬链接,installation,inno-setup,pascalscript,hardlink,Installation,Inno Setup,Pascalscript,Hardlink,我有数千个自己的安装程序需要一个关键的dll文件来完成卸载步骤,这个dll文件的大小大约为2mb,然后为了避免不必要的磁盘空间(2mb*100安装程序),我想在{cf}中存储该文件一次,然后为需要该文件的下一个安装程序创建一个硬链接 我可以在Inno设置中创建硬链接,而不需要外部应用程序,如mklink.exe使用 这是一个简单的示例,我所有的安装程序都遵循相同的“结构”: 如您所见,我正在将uninstall.dll移动到{app},但我想做的是:如果不存在,将uninstall.dll文件复

我有数千个自己的安装程序需要一个关键的dll文件来完成卸载步骤,这个dll文件的大小大约为2mb,然后为了避免不必要的磁盘空间(2mb*100安装程序),我想在
{cf}
中存储该文件一次,然后为需要该文件的下一个安装程序创建一个硬链接

我可以在Inno设置中创建硬链接,而不需要外部应用程序,如mklink.exe使用

这是一个简单的示例,我所有的安装程序都遵循相同的“结构”:

如您所见,我正在将uninstall.dll移动到
{app}
,但我想做的是:如果不存在,将uninstall.dll文件复制到
{cf}\InnoSetup\uninstall.dll
文件路径,并硬链接到
{app}\uninstall.dll
,如果文件已经存在,那么只需进行硬链接,不需要更多,我不会将uninstall.dll文件存储在
{app}\uninstall.dll
中,我只需要一个符号引用,因为uninstall.dll文件永远不应该卸载


我该怎么做?

Inno安装程序不支持以本机方式创建硬链接


我不会考虑外部应用程序。这是一个内置的Windows工具。因此,如果您不需要支持Windows XP,您可以放心地使用它。或者,如果
mklink
不可用,您可以回退到定期安装DLL


或者使用
code
部分中的

#定义MyApp“MyApp”
#定义卸载dll“uninstall.dll”
[档案]
资料来源:“{#卸载DLL}”;DestDir:{cf}\{#MyApp}\
标志:ignoreversion uninsneveruninstall
[守则]
函数CreateHardLink(lpFileName,lpExistingFileName:string;
lpSecurityAttributes:Integer):布尔值;
外部的CreateHardLinkW@kernel32.dllstdcall';
过程CurStepChanged(CurStep:TSetupStep);
变量
ExistingFile,NewFile:string;
开始
如果CurStep=ssPostInstall,则
开始
ExistingFile:=ExpandConstant({cf}\{{MyApp}\{{UninstallDll}');
NewFile:=ExpandConstant('{app}\{{#UninstallDll}');
如果CreateHardLink(新建文件,现有文件,0),则
开始
日志(“创建硬链接”);
结束
其他的
如果FileCopy(ExistingFile、NewFile、False),则
开始
{FAT文件系统?}
日志('无法创建硬链接,改为复制文件');
结束
其他的
开始
MsgBox('无法安装{#卸载DLL}',mbError,MB#U OK);
结束;
结束;
结束;
(在上测试–Inno Setup 6的唯一版本)

卸载时不要忘记删除文件:

过程CurUninstallStep已更改(CurUninstallStep:TUninstallStep);
开始
如果CurUninstallStep=usUninstall,则
开始
如果删除文件(ExpandConstant({app}\{{#UninstallDll}'),则
开始
日志(“文件已删除”);
结束
其他的
开始
日志('无法删除文件');
结束;
结束;
结束;
当然,您也可以使用
[UninstallDelete]
条目。我只是想用与安装该文件相同的技术卸载该文件


您的问题标题是“使用Inno设置创建硬链接”

CreateHardLink
创建一个硬链接。硬链接是对相同内容的另一种引用。基本上,硬链接与原始文件无法区分(甚至原始文件实际上也是硬链接)。原始文件和硬链接只是对相同内容的引用。如果删除原始文件(或新的硬链接),实际上只删除了对内容的一个引用。内容仍然保留着。内容仅在最后一次引用时删除。硬链接不会占用磁盘上的额外空间(内容只存储一次)

有关详细信息,请参阅

默认情况下,
mklink
创建符号链接(也称为符号链接)。符号链接就像快捷方式,它是对原始文件(而不是内容)的引用。它本身就是一个文件,包含目标文件的路径。符号链接有自己的大小(由对目标文件的引用占用)。如果删除原始文件,符号链接仍然存在(因为原始文件中没有对符号链接的引用),但无效(内容消失)。同样,它类似于一条捷径

有关详细信息,请参阅

如果添加
/H
开关,则可以使用
mklink
创建硬链接:

/H创建硬链接而不是符号链接


如果您想创建符号链接而不是硬链接,这是一个不同的问题(尽管答案很简单,但请使用)。尽管如此,请再次注意,硬链接不会占用磁盘上的额外空间,这似乎是您关心的问题。所以我认为您应该继续使用
CreateHardLink
功能。

谢谢您的回答。我会澄清一些事情:1。dll不是我的(它是InnoSetup的VCL样式),因此我无法开发重新编译的函数。2.我们可以将MKLINK.EXE视为一个外部应用程序,它不是INNO安装程序的一部分,很多Windows被“NTLITE”、“WINToToCKIT”等工具“还原”,或者只是用户可以手动删除它,因为它不是一个重要的应用程序。如果我可以在Inno安装程序上从pascal脚本调用WinAPI的CreateHardLink函数,这可能是一个有效的解决方案。以我在问题中给出的例子为例,你能解释一下我如何开发脚本以及何时调用脚本吗?。再次感谢。测试后,它没有按预期工作。mklink.exe应用程序会创建一个0 kb的快捷方式,但CreateHardLink函数会复制相同大小的文件。密码有什么问题?请查看我的赏金信息。
[Files]
; VCL Styles
Source: {tmp}\uninstall.vsf; DestDir: {app}; Flags: ignoreversion
Source: {tmp}\uninstall.dll; DestDir: {app}; Flags: ignoreversion uninsneveruninstall

; Temp files
Source: {tmp}\*; DestDir: {tmp}; Excludes: uninstall.dll, uninstall.vsf; Flags: recursesubdirs createallsubdirs ignoreversion

; Program
Source: {app}\*; DestDir: {app}; Flags: recursesubdirs createallsubdirs ignoreversion