使用 Inno Setup 创建硬链接
Create a hardlink with Inno Setup
我有上千个自己的安装程序,需要一个关键的 dll 文件来进行卸载步骤,这个 dll 文件大小约为 2 mb,然后为了避免不必要的磁盘 space(2mb*100 个安装程序)我想存储在 {cf}
中创建一个文件,然后为下一个需要该文件的安装程序创建一个硬链接。
我可以在 Inno Setup 中创建硬链接,而不需要外部应用程序,例如 mklink.exe usage?
这是我所拥有的一个简短示例,我所有的安装程序都遵循相同的 "structure":
[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 永远不应卸载文件。
我该怎么做?
Inno Setup 不支持本地创建硬盘link。
我不会将 mklink
视为外部应用程序。这是一个 built-in 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]
条目。我只是喜欢使用与安装它相同的技术来卸载该文件。
您的问题标题是"Create a hardlink with Inno Setup".
CreateHardLink
创造了一个困难link。 hardlink 是对相同内容的另一个引用。基本上 hardlink 与原始文件没有区别(即使原始文件实际上是 hardlink)。原始文件和 hardlink 都只是对相同内容的引用。如果您删除原始文件(或新的 hardlink),您实际上只删除了对内容的一个引用。内容仍保留。删除的内容仅包含最后一个参考。硬盘link不额外占用磁盘space(内容只存储一次)
有关详细信息,请参阅 Hard link article on Wikipedia。
虽然 mklink
默认创建一个 symlink(又名符号 link)。 symlink 就像一个快捷方式,它是对原始文件(不是内容)的引用。它本身就是一个文件,其中包含目标文件的路径。 symlink 有自己的大小(被目标文件的引用占用)。如果删除原始文件,symlink 仍然存在(因为原始文件中没有对 symlink 的引用),但变得无效(内容消失了)。同样,它类似于快捷方式。
有关详细信息,请参阅 Symbolic link article on Wikipedia。
如果添加 /H
开关,您可以使用 mklink
创建硬 link:
/H Creates a hard link instead of a symbolic link.
如果你想创建 symlink 而不是 hardlink,这是一个不同的问题(尽管答案很简单,使用 CreateSymbolicLink
function)。不过,请再次注意,硬盘link 不会在磁盘 上占用额外的space,这似乎是您关心的问题。所以我相信你应该继续使用 CreateHardLink
函数。
我有上千个自己的安装程序,需要一个关键的 dll 文件来进行卸载步骤,这个 dll 文件大小约为 2 mb,然后为了避免不必要的磁盘 space(2mb*100 个安装程序)我想存储在 {cf}
中创建一个文件,然后为下一个需要该文件的安装程序创建一个硬链接。
我可以在 Inno Setup 中创建硬链接,而不需要外部应用程序,例如 mklink.exe usage?
这是我所拥有的一个简短示例,我所有的安装程序都遵循相同的 "structure":
[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 永远不应卸载文件。
我该怎么做?
Inno Setup 不支持本地创建硬盘link。
我不会将 mklink
视为外部应用程序。这是一个 built-in 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]
条目。我只是喜欢使用与安装它相同的技术来卸载该文件。
您的问题标题是"Create a hardlink with Inno Setup".
CreateHardLink
创造了一个困难link。 hardlink 是对相同内容的另一个引用。基本上 hardlink 与原始文件没有区别(即使原始文件实际上是 hardlink)。原始文件和 hardlink 都只是对相同内容的引用。如果您删除原始文件(或新的 hardlink),您实际上只删除了对内容的一个引用。内容仍保留。删除的内容仅包含最后一个参考。硬盘link不额外占用磁盘space(内容只存储一次)
有关详细信息,请参阅 Hard link article on Wikipedia。
虽然 mklink
默认创建一个 symlink(又名符号 link)。 symlink 就像一个快捷方式,它是对原始文件(不是内容)的引用。它本身就是一个文件,其中包含目标文件的路径。 symlink 有自己的大小(被目标文件的引用占用)。如果删除原始文件,symlink 仍然存在(因为原始文件中没有对 symlink 的引用),但变得无效(内容消失了)。同样,它类似于快捷方式。
有关详细信息,请参阅 Symbolic link article on Wikipedia。
如果添加 /H
开关,您可以使用 mklink
创建硬 link:
/H Creates a hard link instead of a symbolic link.
如果你想创建 symlink 而不是 hardlink,这是一个不同的问题(尽管答案很简单,使用 CreateSymbolicLink
function)。不过,请再次注意,硬盘link 不会在磁盘 上占用额外的space,这似乎是您关心的问题。所以我相信你应该继续使用 CreateHardLink
函数。