在使用 Inno Setup 更新之前压缩本地文件

Posted

技术标签:

【中文标题】在使用 Inno Setup 更新之前压缩本地文件【英文标题】:Zip local files prior to an update with Inno Setup 【发布时间】:2013-11-07 09:24:51 【问题描述】:

在运行我的安装程序的新版本时,我想通过将文件添加到 ZIP 存档来备份现有安装。

目前,我可以通过将文件复制到我的Backup 目标来备份现有安装。我使用的方法的简化版本如下:

[Files]
; Copy the contents of Bin folder to Backup folder. Skip if files don’t exist. 
Source: app\Bin\*;  DestDir: app\Backup\; \
    Flags: createallsubdirs external recursesubdirs uninsneveruninstall skipifsourcedoesntexist;

如果有任何想法可以代替压缩,我将不胜感激?

【问题讨论】:

我认为例如7-zip 或 zlib DLL 可用于打包文件(如果可以将其函数导出转换为 Inno Setup)。或者,您可以自己编写一个非常简单的单用途 DLL(正如我所看到的,您是一名本地语言程序员)。 【参考方案1】:

您可能想查看 LOGAN ISSI:http://members.home.nl/albartus/inno/index.html 捆绑了一些实用程序。

另一种方法是包含一个批处理文件,该文件将执行备份步骤,然后在完成后将其自行删除。

签出这个帖子:Batch script to zip all the files without the parent folder

但是,由于许可,您不允许将 rar.dll 与您的应用程序捆绑,因此只需应用此方法,但使用可重新分发的包/dll。

如果您可以使用 VBScript 编写一个简单的包装器,您也可以使用内置 zip 压缩的 windows。

看看你怎么样:Can Windows' built-in ZIP compression be scripted?

【讨论】:

【参考方案2】:

我使用了 TLama 的建议,并在 Delphi (XE3) 中创建了自己的 DLL,用于压缩文件夹。

library MyZipLib;
uses
  Winapi.Windows,
  System.SysUtils,
  System.Zip;

$R *.res

function ZipCompressFolder(SourcePath, DestinationPath, ArchiveName : PChar): boolean; stdcall;
begin
  //If source folder does not exist then exit without error.
  if not DirectoryExists(SourcePath) then
  begin
    result := true;
    exit;
  end;

  try
    result := false;

    //Make sure destination path exists
    ForceDirectories(DestinationPath);
    TZipFile.ZipDirectoryContents(IncludeTrailingPathDelimiter(DestinationPath) + ArchiveName, SourcePath);
    result := true;
  except
    on E : Exception do MessageBox(0, PChar('Error calling function ZipCompressFolder@MyZipLib.dll with message: ' + E.Message + #13#10 + 'Source: ' + SourcePath + #13#10 + 'Dest: ' + DestinationPath+ #13#10 + 'Archive: ' + ArchiveName), 'MyZipLib.dll Error', MB_OK);
  end;
end;

exports ZipCompressFolder;
begin
end.

【讨论】:

【参考方案3】:

如果您知道要在具有 .NET 4.5 和更高版本(即 Windows 8 和更高版本)的计算机上进行安装,则可以使用 PowerShell 和 .NET 4.5 ZipFile class from CurStepChanged(ssInstall) event function。

[Code]

procedure CurStepChanged(CurStep: TSetupStep);
var
  Command, AppPath, ZipName, ZipTmpPath, ZipPath: string;
  ResultCode: Integer;
begin
  if CurStep = ssInstall then
  begin
    AppPath := ExpandConstant('app');
    if not DirExists(AppPath) then
    begin
      Log(Format('Application path "%s" does not exist, ' +
        ' probably fresh install, not backing up', [AppPath]));
    end
      else
    begin
      ZipName := 'backup.zip';
      ZipTmpPath := ExpandConstant('tmp') + '\' + ZipName;  
      ZipPath := AppPath + '\' + ZipName;  
      if FileExists(ZipPath) then
      begin
        if DeleteFile(ZipPath) then
          Log(Format('Archive ZIP "%s" exists, deleted', [ZipPath]))
        else
          RaiseException(Format(
            'Archive ZIP "%s" exists, and it could not be deleted', [ZipPath]));
      end;

      Log(Format('Archiving application folder "%s" to temporary "%s"', [
        AppPath, ZipTmpPath]));
      Command :=
        'Add-Type -Assembly System.IO.Compression.FileSystem ; ' +
        '[System.IO.Compression.ZipFile]::CreateFromDirectory(''' +
          AppPath + ''', ''' + ZipTmpPath +''')';
      if Exec('powershell', '-ExecutionPolicy Bypass -command "' + Command + '"',
           '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and
         (ResultCode = 0) then
      begin
        Log(Format('Application folder "%s" archived to temporary "%s"', [
          AppPath, ZipTmpPath]));
      end
        else
      begin
        RaiseException(Format('Error archiving application folder "%s" "%s"', [
          AppPath, ZipTmpPath]));
      end;

      if FileCopy(ZipTmpPath, ZipPath, False) then
        Log(Format('Copied "%s" to "%s"', [ZipTmpPath, ZipPath]))
      else
        RaiseException(Format('Error copying "%s" to "%s"', [
          ZipTmpPath, ZipPath]));
    end;
  end;
end;

如果您需要支持更旧版本的 Windows,您可以使用 Shell.Application 类。虽然我无法让它创建一个 ZIP 文件,但只能添加一个。一个解决方案可能是将一个空的 ZIP 文件添加到安装程序中,然后添加到它。

【讨论】:

以上是关于在使用 Inno Setup 更新之前压缩本地文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 Inno Setup 设置之前运行文件

从Inno Setup中创建ZIP文件

inno setup打包工具的使用问题?

在 Inno Setup 中运行 schtask.exe 之前使用安装路径创建 XML 任务文件

inno setup打包成安装文件

使用 Inno Setup 升级 Windows 服务