【问题标题】:Create a hardlink with Inno Setup使用 Inno Setup 创建硬链接
【发布时间】:2015-10-06 00:52:14
【问题描述】:

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

我可以在 Inno Setup 中创建硬链接而不需要使用 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

如您所见,我将 uninstall.dll 移动到 {app},但我想做的是:如果不存在,请复制 uninstall。 dll 文件到{cf}\InnoSetup\uninstall.dll 文件路径并建立到{app}\uninstall.dll 的硬链接,如果该文件已经存在则只需建立硬链接,仅此而已,我不会仍然存储 uninstall.dll {app}\uninstall.dll 中的文件,只是我想要一个符号引用,因为永远不应该卸载 uninstall.dll 文件。

我该怎么做?

【问题讨论】:

    标签: installation inno-setup pascalscript hardlink


    【解决方案1】:

    Inno Setup 不支持原生创建硬链接。


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


    或使用Code 部分中的CreateHardLink function

    #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 Setup 创建硬链接

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

    详情请见Hard link article on Wikipedia

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

    详情见Symbolic link article on Wikipedia

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

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

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

    【讨论】:

    • 感谢您的回答。我将澄清一些事情: 1. dll 不是我的(它是 InnoSetup 的 VCL 样式)然后我无法开发重新编译的功能。 2. 我们可以将 mklink.exe 视为一个外部应用程序,这意味着它不属于 Inno Setup 的一部分,许多 Windows 都使用 NTLite、WinToolKit 等工具“减少”,或者只是它可以由用户手动删除,因为不是一个重要的应用程序。
    • 那么,如果我可以从 Inno Setup 上的 pascal-script 调用 WinAPI 的 CreateHardLink 函数,这可能是一个有效的解决方案。以我在问题中给出的示例为例,您能否解释一下我如何开发脚本以及何时调用它?再次感谢。
    • 经过测试,它没有按预期工作。 mklink.exe 应用程序创建了一个 0 kb 的快捷方式,但 CreateHardLink 函数复制了相同大小的文件。代码有什么问题?
    • 请看我的赏金信息。
    猜你喜欢
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 2015-12-21
    • 2015-11-22
    • 1970-01-01
    • 2016-03-04
    • 2011-03-24
    • 1970-01-01
    相关资源
    最近更新 更多