Создать жесткую ссылку с Inno Setup

У меня есть тысяча собственных инсталляторов, для которых требуется критический файл dll для шага деинсталляции, этот размер файла dll составляет около 2 МБ, тогда, чтобы избежать ненужного дискового пространства (2 МБ *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 никогда не должен быть удален.

Как я мог это сделать?

1 ответ

Решение

Inno Setup не поддерживает создание жестких ссылок.


Я бы не стал рассматривать mklink внешнее приложение. Это встроенный инструмент Windows. Так что если вам не нужна поддержка Windows XP, вы можете смело полагаться на нее. Или вы можете вернуться к установке DLL регулярно, если mklink не доступен.


Или используйте CreateHardLink функция от 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-версии 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 создает жесткую ссылку. Жесткая ссылка - это еще одна ссылка на то же содержание. По сути, жесткая ссылка неотличима от исходного файла (даже исходный файл на самом деле является жесткой ссылкой). И оригинальный файл, и жесткая ссылка являются просто ссылками на одно и то же содержимое. Если вы удаляете исходный файл (или новую жесткую ссылку), вы фактически удаляете только одну ссылку на содержимое. Содержание все еще сохраняется. Содержание удаляется только с последней ссылкой. Жесткая ссылка не занимает дополнительного места на диске (содержимое сохраняется только один раз).

Подробнее см. Статью с жесткой ссылкой в ​​Википедии.

В то время как mklink создает символическую ссылку (она же символическая ссылка) по умолчанию. Символьная ссылка похожа на ярлык, это ссылка на оригинальный файл (не на содержимое). Это отдельный файл, который содержит путь к целевому файлу. Символьная ссылка имеет собственный размер (занятый ссылкой на целевой файл). Если вы удаляете исходный файл, символическая ссылка все еще существует (потому что нет ссылки на символическую ссылку из исходного файла), но становится недействительной (содержимое исчезло). Опять же, это похоже на ярлык.

Для получения дополнительной информации см. Статью "Символическая ссылка" в Википедии.

Вы можете создать жесткую ссылку с mklink, если вы добавите /H переключатель:

/ H Создает жесткую ссылку вместо символической ссылки.

Если вы хотите создать символическую ссылку вместо жесткой ссылки, это другой вопрос (хотя ответ прост, используйте CreateSymbolicLink функция). Тем не менее, обратите внимание, что жесткая ссылка не занимает дополнительного места на диске, что, по-видимому, является вашей проблемой. Поэтому я считаю, что вы должны продолжать использовать CreateHardLink функция.

Другие вопросы по тегам