2015-10-06 93 views
4

我有自己的安装程序,需要的卸载步骤至关重要的DLL文件万辆,这个dll文件大小约2 MB,然后以避免不必要的磁盘空间(2MB×100组的安装程序)我想存储在{cf}文件一次,然后为需要该文件的下一个安装程序建立一个硬链接。创建Inno Setup的硬链接

我可以在Inno安装程序中创建一个硬链接,而不需要外部应用程序,如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文件不应该被卸载。

我该怎么做?

回答

5

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 '[email protected] 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版本Inno Setup的的)

和卸载

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创建了一个硬链接。硬链接是对相同内容的另一个参考。基本上硬链接与原文件没有区别(甚至是原始文件是固网实际上)。原始文件和硬链接都只是对相同内容的引用。如果删除原始文件(或新的硬链接),则实际上只删除一个对内容的引用。内容仍然保留。内容仅在最后一个参考中被删除。硬链接不会占用磁盘上的额外空间(内容仅存储一次)。

详情请参阅Hard link article on Wikipedia

默认情况下,mklink创建符号链接(又名符号链接)。符号链接就像一个快捷方式,它是对原始文件(而不是内容)的引用。这是一个独立的文件,它包含目标文件的路径。符号链接具有自己的大小(由目标文件的引用占用)。如果删除原始文件,则符号链接仍然存在(因为没有引用来自原始文件的符号链接),但变为无效(内容已消失)。再次,它类似于一条捷径。

详情请参阅Symbolic link article on Wikipedia

您可以创建一个固网与mklink,如果添加/H开关:

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

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

+0

感谢您的回答。我将澄清一些事情:1. DLL不是我的(它是InnoSetup的VCL样式),那么我不能开发一个函数来重新编译。 2.我们可以将mklink.exe视为外部应用程序,其意义不在于Inno Setup的部分内容,许多Windows使用NTLite,WinToolKit等工具“减少”,或者只能由用户手动删除,因为不是一个重要的应用程序。 – ElektroStudios

+0

然后,如果我可以从Inno Setup上的pascal-script调用WinAPI的** CreateHardLink **函数,这可能是一个有效的解决方案。以我在问题中给出的例子,你能解释我该如何开发脚本,何时给它打电话?再次感谢。 – ElektroStudios

+1

看到我编辑的答案。 –