如何使用 Inno Setup Install / DswinDs 系统处理 DotNet 先决条件?

How to handle DotNet prerequisite with Inno Setup Install / DswinDs system?

我现在了解如何使用此 DswinsHs 下载 文件(因为我们在帮助文档中使用它).

但现在我需要迁移一些可选下载并安装的旧代码Dot Net Framework.

旧代码

我有这段代码(使用 ISTool DLL):

const
  // Changed to 4.6.2 download link (see: http://msdn.microsoft.com/en-us/library/ee942965%28v=vs.110%29.aspx#redist)
  dotnetRedistURL = 'http://go.microsoft.com/fwlink/?LinkId=780600';

function PrepareToInstall(var NeedsRestart: Boolean): String;
var
 IsInstalled: Cardinal;
begin
  Result := '';
  dotNetNeeded := true;

  // Check for required netfx installation
  // http://msdn.microsoft.com/en-us/library/hh925568%28v=vs.110%29.aspx#net_b
  if(Is64BitInstallMode()) then begin
    if (RegValueExists(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release')) then begin
      RegQueryDWordValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', IsInstalled);
      if(IsInstalled >= 378675) then begin
        dotNetNeeded := false;
        downloadNeeded := false;
      end;
    end;
  end
  else begin
    if (RegValueExists(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release')) then begin
      RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', IsInstalled);
      if(IsInstalled >= 378675) then begin
        dotNetNeeded := false;
        downloadNeeded := false;
      end;
    end;
  end;

  if(dotNetNeeded) then begin
    if (not IsAdminLoggedOn()) then begin
      Result := ExpandConstant('{cm:DotNet_NeedAdminRights}');
    end
    else begin
      dotnetRedistPath := ExpandConstant('{src}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
      if not FileExists(dotnetRedistPath) then begin
        dotnetRedistPath := ExpandConstant('{tmp}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
        if not FileExists(dotnetRedistPath) then begin
          isxdl_AddFile(dotnetRedistURL, dotnetRedistPath);
          downloadNeeded := true;
        end;
      end;

      if (downloadNeeded) then begin
        if (MsgBox(ExpandConstant('{cm:DotNet_NeedToDownload}'), mbConfirmation, MB_OKCANCEL) = IDCANCEL) then begin
          Result := ExpandConstant('{cm:DotNet_InstallAborted}');
        end;
      end;
    end;
  end;

  // AJT v19.0.0 We always delete the existing local help file if it exists.
  // The new version will be downloaded on the next wizard form if
  // the user still wants the local help. ("downloadhelp" task selected).
  if (bDownloadHelpDocSetup) then DoDeleteFile(ExpandConstant('{app}\CommunityTalks.chm'));

 end;

那么我有:

procedure CurStepChanged(CurStep: TSetupStep);
var
  hWnd: Integer;
  ResultCode: Integer;
begin
  if (CurStep = ssInstall) then
  begin
    hWnd := StrToInt(ExpandConstant('{wizardhwnd}'));

    // Don't try to init isxdl if it's not needed because it will error on < ie 3
    if (downloadNeeded) then begin
      isxdl_SetOption('label', ExpandConstant('{cm:Downloading}'));
      isxdl_SetOption('description', ExpandConstant('{cm:DownloadingInfo}'));
      if (isxdl_DownloadFiles(hWnd) = 1) then begin
        if (dotNetNeeded = true) then begin
          if Exec(ExpandConstant(dotnetRedistPath), '/quiet', '',
                 SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
            // handle success if necessary; ResultCode contains the exit code
            if not (ResultCode = 0) then begin
              // Microsoft present an array of options for this. But since
              // The interface was visible I think it is safe to just say
              // that the installation was not completed.
              MsgBox(ExpandConstant('{cm:DotNet_InstallFailed}'), mbInformation, MB_OK);
              Abort();
            end;
          end
          else begin
            // The execution failed for some reason
            MsgBox(SysErrorMessage(ResultCode), mbInformation, MB_OK);
            Abort();
          end;
        end;
      end
      else begin
        // The user most likely cancelled the download of the file
        MsgBox(ExpandConstant('{cm:DotNet_DownloadFailed}'), mbInformation, MB_OK);
        Abort();
      end;
    end;
    end;
end;

这需要改变。


DswinsHs 是如何完成的

对于与 DwinsHs 兼容的下载,我基本上有 两位,如下所示:

    ; AJT v19.0.0 Download Help Documentation Setup file.
    ; This is associated with the "downloadhelp" task.
    ; It will be downloaded from the internet and deleted after install.
    Source: "{tmp}\HelpDocSetup.exe"; \
        DestDir: "{app}"; \
        Flags: external deleteafterinstall; \
        Tasks: downloadhelp; \
        Check: DwinsHs_Check( ExpandConstant('{tmp}\HelpDocSetup.exe'), '{#HelpDocSetupURL}', \
                'My_Setup', 'Get', {#HelpDocSetupFileSize}, 0 )
    ; AJT v19.0.0 Installed the downloaded help documentation.
    ; This is only done if the "downloadhelp" task was selected.
    Filename: "{app}\HelpDocSetup.exe"; \
        Parameters: "/SP- /VERYSILENT /InstallPath=""{app}"""; \
        WorkingDir: "{app}"; \
        Flags: waituntilterminated runhidden; \
        Description: "{cm:InstallingHelpDescription}"; \
        StatusMsg: "{cm:InstallingHelpStatusMessage}"; \
        Tasks: downloadhelp

问题

我需要将我以前的代码(DotNet 先决条件)转换成合适的文件/运行 脚本行(除了这次我必须为文件大小传递 0,因为我不知道大小)。

简而言之,我的设置需要管理员权限,从技术上讲,我们需要它来下载和安装 dotnet(如果不存在)然后继续设置。原因是我们有这些 运行 个条目:

Filename: "{dotnet40}\regasm.exe"; \
    Parameters: "PTSTools_x86.dll /codebase"; \
    WorkingDir: "{app}"; \
    Flags: runhidden

Filename: "{dotnet4064}\regasm.exe"; \
    Parameters: "PTSTools_x64.dll /codebase"; \
    WorkingDir: "{app}"; \
    Flags: runhidden; \
    Check: IsWin64

Filename: "{dotnet40}\regasm.exe"; \
    Parameters: "/u PTSTools_x86.dll"; \
    WorkingDir: "{app}"; \
    Flags: runhidden; \
    Check: FileExists(ExpandConstant('{app}\PTSTools.dll')); \
    AfterInstall: DoDeleteFile(ExpandConstant('{app}\PTSTools.dll'))

Filename: "{dotnet4064}\regasm.exe"; \
    Parameters: "/u PTSTools.dll"; \
    WorkingDir: "{app}"; \
    Flags: runhidden; \
    Check: IsWin64 and FileExists(ExpandConstant('{app}\PTSTools.dll')); \
    AfterInstall: DoDeleteFile(ExpandConstant('{app}\PTSTools.dll'))

所以拥有 DotNet 是安装程序工作的先决条件。我应该以不同的方式处理这个问题吗?


我这样做对吗?

根据提供的答案和我对文档的理解...

第 1 步

PrepareToInstall中我们检查是否需要 DotNet 并缓存结果:

function PrepareToInstall(var NeedsRestart: Boolean): String;
var
 IsInstalled: Cardinal;
begin
  Result := '';
  dotNetNeeded := true;

  // Check for required netfx installation
  // http://msdn.microsoft.com/en-us/library/hh925568%28v=vs.110%29.aspx#net_b
  if(Is64BitInstallMode()) then begin
    if (RegValueExists(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release')) then begin
      RegQueryDWordValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', IsInstalled);
      if(IsInstalled >= 378675) then begin
        dotNetNeeded := false;
      end;
    end;
  end
  else begin
    if (RegValueExists(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release')) then begin
      RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', IsInstalled);
      if(IsInstalled >= 378675) then begin
        dotNetNeeded := false;
      end;
    end;
  end;

  if(dotNetNeeded) then begin
    if (MsgBox(ExpandConstant('{cm:DotNet_NeedToDownload}'), mbConfirmation, MB_OKCANCEL) = IDCANCEL) then begin
      Result := ExpandConstant('{cm:DotNet_InstallAborted}');
    end;
  end;

 end;

第 2 步

我们添加一个 BeforeDownload 处理程序。这是我们将需要下载的文件添加到列表的地方:

function BeforeDownload(): Boolean;
 begin
  if(dotNetNeeded) then
  begin
    dotNetRedistPath := ExpandConstant('{tmp}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
    DwinsHs_AppendRemoteFile( dotNetRedistPath, \
                  dotnetRedistURL, 'My_Setup', rmGet, FILESIZE_QUERY_SERVER );
  end;

  Result := True;
end;

第 3 步

我们添加一个 AfterDownload 处理程序。这是我们执行 DotNet 安装的地方。

procedure AfterDownload(State: Integer);
var
  hWnd: Integer;
  ResultCode: Integer;
begin
  if (State = READ_OK) then
  begin
    if(dotNetNeeded) then
    begin
      if Exec(ExpandConstant(dotnetRedistPath), '/quiet', '',
          SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
        // handle success if necessary; ResultCode contains the exit code
        if not (ResultCode = 0) then begin
          // Microsoft present an array of options for this. But since
          // The interface was visible I think it is safe to just say
          // that the installation was not completed.
          MsgBox(ExpandConstant('{cm:DotNet_InstallFailed}'), mbInformation, MB_OK);
          Abort();
        end;
      end
      else begin
        // The execution failed for some reason
        MsgBox(SysErrorMessage(ResultCode), mbInformation, MB_OK);
        Abort();
      end;
    end;
  end;
end;

我不确定现在 "quiet" 是否正确...

第 4 步

我们调整 CurPageChanged 处理程序:

procedure CurPageChanged(CurPage: Integer);
begin
  DwinsHs_CurPageChanged(CurPage, @BeforeDownload, @AfterDownload);
end;

dotNetNeeded 时调用 DwinsHs_AppendRemoteFile

DwinsHs_AppendRemoteFileDwinsHs_Check 具有基本相同的参数(DwinsHs_Check 实际上只是 DwinsHs_AppendRemoteFileCheck 兼容包装器)。

我相信这就是您所需要的。 [Run] 仅在下载后发生。