I have thousand of own installers that requires a critical dll file for uninstallation step, this dll file sizes about 2 mb then to avoid unnecessary disk space (2mb*100 ins
Inno Setup does not support creating hardlinks natively.
I wouldn't consider the mklink an external application. It's a built-in Windows tool. So if you do not need to support Windows XP, you can safely rely on it. Or you can fallback to installing the DLL regularly, if the mklink
is not available.
Or use the CreateHardLink function from the Code
section.
#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;
(Tested on Unicode version of Inno Setup – The only version as of Inno Setup 6)
And do not forget to delete the file when uninstalling:
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;
You can of course use also the [UninstallDelete]
entry. I just like to uninstall the file using the same technology used to install it.
Your question title is "Create a hardlink with Inno Setup".
The CreateHardLink
creates a hardlink. A hardlink is another reference to the same contents. Basically the hardlink is indistinguishable from the original file (even the original file is a hardlink actually). Both original file and the hardlink are just references to the same contents. If you delete the original file (or the new hardlink), you actually remove just one reference to the contents. The contents is still preserved. The contents is removed with the last reference only. The hardlink does not occupy an additional space on the disk (the contents is stored only once).
For details see Hard link article on Wikipedia.
While the mklink
creates a symlink (aka symbolic link) by default. A symlink is like a shortcut, it's a reference to the the original file (not contents). It's a file on its own, that contains a path to the target file. The symlink has a size of its own (occupied by the reference to the target file). If you remove the original file, the symlink still exists (because there's no reference to the symlink from the original file), but becomes invalid (the contents is gone). Again, it's similar to a shortcut.
For details see Symbolic link article on Wikipedia.
You can create a hardlink with the mklink
, if you add the /H
switch:
/H Creates a hard link instead of a symbolic link.
If you want to create the symlink instead of the hardlink, it's a different question (though the answer is simple, use the CreateSymbolicLink function). Though again, note that the hardlink does not occupy additional space on the disk, what seems to be your concern. So I believe you should keep using the CreateHardLink
function.