installation - 使用 Inno Setup 创建硬链接(hard link)

标签 installation inno-setup pascalscript hardlink

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

我可以在 Inno Setup 中创建硬链接(hard link),而不需要外部应用程序,例如 mklink.exe 用法?

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

[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

如您所见,我正在移动 卸载.dll {app} ,但我想做的是:如果不存在,复制卸载.dll 文件到 {cf}\InnoSetup\uninstall.dll文件路径并建立到 {app}\uninstall.dll 的硬链接(hard link),如果文件已经存在,那么就做硬链接(hard link),仅此而已,我还是不会存储卸载.dll 文件在 {app}\uninstall.dll ,只是我想要一个符号引用,因为 卸载.dll 文件永远不应该被卸载。

我怎么能做到?

最佳答案

Inno Setup 不支持原生创建硬链接(hard link)。

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

或使用 CreateHardLink function来自 Code部分。

#define MyApp "MyApp"
#define UninstallDll "uninstall.dll"

[Files]
Source: "{#UninstallDll}"; DestDir: "{cf}\{#MyApp}"; \
  Flags: ignoreversion uninsneveruninstall

[Code]
function CreateHardLink(lpFileName, lpExistingFileName: string;
  lpSecurityAttributes: Integer): Boolean;
  external 'CreateHardLinkW@kernel32.dll stdcall';

procedure CurStepChanged(CurStep: TSetupStep);
var
  ExistingFile, NewFile: string;
begin
  if CurStep = ssPostInstall then
  begin
    ExistingFile := ExpandConstant('{cf}\{#MyApp}\{#UninstallDll}');
    NewFile := ExpandConstant('{app}\{#UninstallDll}');
    if CreateHardLink(NewFile, ExistingFile, 0) then
    begin
      Log('Hardlink created');
    end
      else
    if FileCopy(ExistingFile, NewFile, False) then
    begin
      { FAT file system? }
      Log('Hardlink could not be created, file copied instead');
    end
      else
    begin
      MsgBox('Cannot install {#UninstallDll}', mbError, MB_OK);
    end;
  end;
end;

(测试于 Unicode version of Inno Setup – Inno Setup 6 的唯一版本)

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

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usUninstall then
  begin
    if DeleteFile(ExpandConstant('{app}\{#UninstallDll}')) then
    begin
      Log('File deleted');
    end
      else
    begin
      Log('Cannot delete file');
    end;
  end;
end;

您当然也可以使用 [UninstallDelete]入口。我只是喜欢使用与安装它相同的技术来卸载该文件。

您的问题标题是“使用 Inno 设置创建 硬链接(hard link) ”。
CreateHardLink创建一个 硬链接(hard link) .硬链接(hard link)是对相同内容的另一个引用。基本上,硬链接(hard link)与原始文件无法区分(即使原始文件实际上也是硬链接(hard link))。原始文件和硬链接(hard link)都只是对相同内容的引用。如果您删除原始文件(或新的硬链接(hard link)),您实际上只删除了对内容的一个引用。内容仍然保留。内容仅与最后一次引用一起被删除。硬链接(hard link)不会占用磁盘上的额外空间(内容只存储一次)。

详情见Hard link article on Wikipedia .

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

详情见Symbolic link article on Wikipedia .

您可以使用 mklink 创建硬链接(hard link), 如果您添加 /H转变:

/H Creates a hard link instead of a symbolic link.



如果你想创建符号链接(symbolic link)而不是硬链接(hard link),这是一个不同的问题(虽然答案很简单,使用 CreateSymbolicLink function )。尽管如此,请注意硬链接(hard link) 不占用磁盘上的额外空间 ,你关心的似乎是什么。所以我相信你应该继续使用CreateHardLink功能。

关于installation - 使用 Inno Setup 创建硬链接(hard link),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32960082/

相关文章:

java - IntelliJ IDEA 是否可以在 64 位 Windows 系统上运行?

installation - Wix 重大升级

inno-setup - 自动重试删除要使用 Inno Setup 替换的文件

installation - Inno-setup:基于现有页面类型的自定义向导页面

inno-setup - Inno 安装程序 : access violation using IShellLink GetWorkingDirectory

inno-setup - Inno 安装程序 : Marquee style progress bar for lengthy synchronous operation in C# DLL

ionic-framework - ionic 包无法安装

java - 如何安装/配置自定义 Java 外观?

inno-setup - Inno Setup 32位和64位dll安装

inno-setup - 将自定义按钮与 Inno Setup 取消按钮对齐