Как заставить Inno Setup распаковать файл, который он установил (все как часть одного процесса установки)

Чтобы сохранить пропускную способность и пространство, а также предотвратить случайное вмешательство, файлы установки для продукта базы данных (назовите его Ajax) были заархивированы (вызовите этот файл "AJAX_Install_Files.ZIP" ). Я хотел бы иметь Inno-Setup "установить" (то есть скопировать) файл AJAX_Install_Files.ZIP в пункт назначения, а затем разархивировать файлы в ту же папку, где находится файл .ZIP. Последующая программа будет запущена Inno Setup, чтобы фактически запустить установку продукт "Ajax".

Я просмотрел документацию, FAQ и KB на веб-сайт Inno Setup, и это не представляется возможным, кроме написания Pascal script (код) - это было бы правильно или есть альтернативные решения?

Ответ 1

Вы можете использовать инструмент внешней командной строки для распаковки вашего архива, например, здесь. Поместите его в раздел [Files]:

[Files]
Source: "UNZIP.EXE"; DestDir: "{tmp}"; Flags: deleteafterinstall

Затем вызовите его в разделе [Run], например:

[Run]
Filename: "{tmp}\UNZIP.EXE"; Parameters: "{tmp}\ZipFile.ZIP -d C:\TargetDir"

(Вероятно, вы захотите взять целевой каталог из переменной script, поэтому необходимо выполнить еще одну работу)

Ответ 2

Вы можете использовать метод Folder.CopyHere для извлечения ZIP.

const
  SHCONTCH_NOPROGRESSBOX = 4;
  SHCONTCH_RESPONDYESTOALL = 16;

procedure UnZip(ZipPath, TargetPath: string); 
var
  Shell: Variant;
  ZipFile: Variant;
  TargetFolder: Variant;
begin
  Shell := CreateOleObject('Shell.Application');

  ZipFile := Shell.NameSpace(ZipPath);
  if VarIsClear(ZipFile) then
    RaiseException(Format('ZIP file "%s" does not exist or cannot be opened', [ZipPath]));

  TargetFolder := Shell.NameSpace(TargetPath);
  if VarIsClear(TargetFolder) then
    RaiseException(Format('Target path "%s" does not exist', [TargetPath]));

  TargetFolder.CopyHere(ZipFile.Items, SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);
end;

Обратите внимание, что флаги SHCONTCH_NOPROGRESSBOX и SHCONTCH_RESPONDYESTOALL работают в Windows Vista и новее.


Для примера извлечения только некоторых файлов см.:
Как заставить Inno Setup распаковать один файл?

Ответ 3

Я ответил на очень похожий вопрос , и некоторые из них касаются.

Я бы спросил, зачем вам нужен ZIP файл? Я лично разместил несжатые файлы в настройках. Тогда у меня было бы две записи [category] для приложения и одна для данных. По умолчанию оба проверяются.

Это позволит пользователям установить свежий набор данных, если потребуется, на более позднюю дату.

Если вам действительно нужен ZIP файл и вы хотите сохранить его легко, отправляйте оба ZIP файла и несжатые файлы в одну и ту же настройку.

Update:

По умолчанию файлы, которые помещаются в ваш файл setup.exe, сжаты.

Вы также можете извлечь файлы во временное место, чтобы вы могли запускать свои затем удалите их.

[Files]
Source: "Install1.SQL"; DestDir: "{tmp}"; Flags:deleteafterinstall;
Source: "Install2.SQL"; DestDir: "{tmp}"; Flags:deleteafterinstall;

Ответ 4

Вы можете просто создать тихий самораспаковывающийся архив (SFX), пример, описанный здесь, как создать SFX-архив для вещей, которые вам нужны, и написать код на Pascal, чтобы просто запустить его следующим образом (скрипт для Inno Setup 6.0.2):

[Tasks]
Name: "intallSenselockDriver"; Description: "Install Senselock driver."; GroupDescription: "Install the necessary software:";

[Code]
function ExecTmpFile(FileName: String): Boolean;
var
  ResultCode: Integer;
begin
  if not Exec(ExpandConstant('{tmp}\' + FileName), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode)
  then
    begin
      MsgBox('Other installer failed to run!' + #13#10 + SysErrorMessage(ResultCode), mbError, MB_OK);
      Result := False;
    end
  else
    Result := True;
end;

procedure RunOtherInstallerSFX(ArchiveName: String; ExePath: String);
begin
  ExtractTemporaryFile(ArchiveName);
  ExecTmpFile(ArchiveName);
  ExecTmpFile(ExePath);
end;

function PrepareToInstall(var NeedsRestart: Boolean): String;
begin
  if WizardIsTaskSelected('intallSenselockDriver') then
    RunOtherInstallerSFX('1_senselock_windows_3.1.0.0.exe', '1_senselock_windows_3.1.0.0\InstWiz3.exe');

  Result := '';
end;

Это отлично сработало для меня.