You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Inno Setup中按用户选择的组件下载并解压指定文件

Inno Setup 组件按需下载与解压进度优化方案

现存问题分析

  1. 无差别下载解压:当前代码在准备安装阶段直接下载完整的1.4GB压缩包,完全不判断用户选中的组件,导致无论选什么都要处理全部文件,耗时极长。
  2. 无解压进度反馈:解压时使用了NO_PROGRESS_BOX标志,系统不显示解压进度,用户无法感知安装状态。

解决方案一:现有单压缩包下的按需解压(快速优化)

如果暂时无法拆分压缩包,可通过只解压选中组件对应目录减少耗时,同时恢复解压进度提示。

修改后的完整代码

[Files]
Source: "{tmp}\packs\Sapphic_icons\Dead by Daylight\DeadByDaylight\Content\UI\Icons\README.txt"; DestDir: "{app}"; Components: sapphic; Flags: ignoreversion recursesubdirs createallsubdirs external; Check: IsComponentSelectedAndNeedsInstall("sapphic")

[Types]
Name: "sapphic"; Description: "Sapphic Pack";
Name: "custom"; Description: "Customized"; Flags: iscustom;

[Components]  
Name: "sapphic"; Description: "Sapphic Pack - WIP*"; Types: custom sapphic;

[Code]
{ —————————— 解压工具函数 ———————————————————————————————————————— }
const
  RESPOND_YES_TO_ALL = 16; // 移除NO_PROGRESS_BOX,显示系统解压进度条
procedure UnZip(ZipPath, SourceDir, TargetPath: string); 
var
  Shell: Variant;
  ZipFile: Variant;
  Item: Variant;
  TargetFolder: Variant;
begin
  Shell := CreateOleObject('Shell.Application');

  ZipFile := Shell.NameSpace(ZipPath);
  if VarIsClear(ZipFile) then
    RaiseException(Format('无法打开ZIP文件 "%s" 或文件不存在', [ZipPath]));

  Item := ZipFile.ParseName(SourceDir);
  if VarIsClear(Item) then
    RaiseException(Format('在ZIP文件 "%s" 中找不到 "%s"', [SourceDir, ZipPath]));

  TargetFolder := Shell.NameSpace(TargetPath);
  if VarIsClear(TargetFolder) then
    RaiseException(Format('目标路径 "%s" 不存在', [TargetPath]));

  TargetFolder.CopyHere(Item, RESPOND_YES_TO_ALL);
end;

{ —————————— 组件安装检查函数 ———————————————————————————————————————— }
function IsComponentSelectedAndNeedsInstall(ComponentName: string): Boolean;
var 
  TargetPath: String; 
begin  
  // 检查组件是否被选中,且目标目录不存在
  Result := (IsComponentSelected(ComponentName)) and 
            (not DirectoryExists(ExpandConstant('{userappdata}\App\packs\' + ComponentName + '_icons')));
  Log(Format('组件%s安装检查结果: %d', [ComponentName, Result]));  
end;

{ —————————— 下载进度回调 ———————————————————————————————————————— }
var
  DownloadPage: TDownloadWizardPage;
function OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64): Boolean;
begin
  if Progress = ProgressMax then
    Log(Format('文件已成功下载到{tmp}: %s', [FileName]));
  Result := True;
end;

{ —————————— 初始化向导 ———————————————————————————————————————— }
procedure InitializeWizard();
begin
  DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), @OnDownloadProgress);
end;

{ —————————— 下一步按钮逻辑 ———————————————————————————————————————— } 
function NextButtonClick(CurPageID: Integer): Boolean;
var  
  Temp: String;
  NeedDownload: Boolean;
begin
  Result := True;
  if CurPageID = wpReady then begin
      // 判断是否有选中的组件需要下载解压
      NeedDownload := IsComponentSelectedAndNeedsInstall('sapphic');
      
      if NeedDownload then begin
          DownloadPage.Clear;
          DownloadPage.Add('https://www.dropbox.com/scl/fi/fautmpacdsl22h6y41jrv/packs.zip?rlkey=ul3kl1f9o3258yguitprisx6c&st=wwry4esv&dl=1', 'packs.zip', '');
          DownloadPage.Show;
          try
            try
              DownloadPage.Download;
              Temp := ExpandConstant('{tmp}');
              // 只解压选中组件对应的目录
              if IsComponentSelected('sapphic') then
                UnZip(Temp+'\packs.zip', 'packs/Sapphic_icons', Temp);
            except
              SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
              Result := False;
            end;
          finally
            DownloadPage.Hide;
          end;
      end;
  end;
end;

关键修改点

  1. 移除解压无进度标志:删除NO_PROGRESS_BOX,让系统显示默认的解压进度窗口,给用户明确反馈。
  2. 组件按需解压:在NextButtonClick中判断用户选中的组件,只解压对应目录(如sapphic组件对应packs/Sapphic_icons)。
  3. 优化安装检查逻辑:新增IsComponentSelectedAndNeedsInstall函数,同时检查组件是否被选中、目标目录是否存在,避免重复解压。

解决方案二:分组件打包实现真正按需下载(彻底优化)

如果要完全避免下载未选中组件的文件,需将每个组件的资源单独打包,再根据用户选择动态下载对应压缩包。

核心修改思路

  1. 拆分压缩包:将Sapphic Pack单独打包为sapphic_packs.zip,其他组件同理。
  2. 动态添加下载任务:在NextButtonClick中遍历选中的组件,添加对应压缩包的下载链接。
  3. 逐个解压对应组件:下载完成后,仅解压当前选中组件的压缩包。

内容的提问来源于stack exchange,提问作者Lilith Helsente

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:08:14