如何使用InnoSetup安装.NET框架作为先决条件?

 立案whan_597 发布于 2023-02-08 13:33

我有一个类似于Inno Setup的问题:验证是否已安装.NET 4.0,但它似乎略有不同.

[Files]
Source: "dependencies\dotNetFx40_Full_x86_x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall; Check: FrameworkIsNotInstalled
Source: "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\MySql.Data\v4.0_6.5.4.0__c5687fc88969c44d\MySql.Data.dll"; DestDir: "{app}\lib"; StrongAssemblyName: "MySql.Data, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, ProcessorArchitecture=MSIL"; Flags: "gacinstall sharedfile uninsnosharedfileprompt"

[Run]
Filename: {tmp}\dotNetFx40_Full_x86_x64.exe; Description: Install Microsoft .NET Framework 4.0; Parameters: /q /norestart; Check: FrameworkIsNotInstalled

[code]
function FrameworkIsNotInstalled: Boolean;
begin
  Result := not RegKeyExists(HKEY_LOCAL_MACHINE, 'Software\Microsoft\.NETFramework\policy\v4.0');
end;

如您所见,我正在尝试向GAC注册文件.不幸的是,在某些机器上可能没有安装.NET框架.所以我需要先安装它.无论如何,我尝试注册文件之前,我是否可以强制安装.NET运行时?

3 个回答
  • 由于该[Run]部分是在该[Files]部分之后处理的,因此使用您显示的脚本(因此您的问题)自然无法做到这一点.我建议使用的方法是从AfterInstallsetup条目本身的参数函数执行.NET设置.因此,您将删除当前[Run]部分并编写如下脚本:

    [Files]
    Source: "dependencies\dotNetFx40_Full_x86_x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall; AfterInstall: InstallFramework; Check: FrameworkIsNotInstalled
    Source: "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\MySql.Data\v4.0_6.5.4.0__c5687fc88969c44d\MySql.Data.dll"; DestDir: "{app}\lib"; StrongAssemblyName: "MySql.Data, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, ProcessorArchitecture=MSIL"; Flags: gacinstall sharedfile uninsnosharedfileprompt
    
    [Code]
    procedure InstallFramework;
    var
      ResultCode: Integer;
    begin
      if not Exec(ExpandConstant('{tmp}\dotNetFx40_Full_x86_x64.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
      begin
        { you can interact with the user that the installation failed }
        MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.',
          mbError, MB_OK);
      end;
    end;
    

    这个过程很简单,如果该Check部分的.NET设置条目的功能[Files]评估为True(FrameworkIsNotInstalled),则处理该条目,将设置二进制文件复制到Inno Setup的临时文件夹中,如果成功,则立即调用该AfterInstall函数.InstallFramework.在此函数内部,通过调用Exec函数手动执行.NET设置.

    最后,如果所有这些都成功,安装将继续处理下一个[Files]部分条目,即您要注册的程序集.现在,使用已安装的.NET框架.正如您所看到的,[Files]部分条目的顺序在这里至关重要.


    您还在评论中另外询问了如何向用户显示一些进展,因为以我在此处发布的方式执行.NET设置会阻止该[Files]条目,这会导致显示已停止的进度条和有关提取文件的文本.由于获取.NET安装程序的安装进度并不容易,因此我只是在设置执行期间向用户显示无限的选取框进度条.

    为此,将设置执行包装成如下代码:

    procedure InstallFramework;
    var
      StatusText: string;
    begin
      StatusText := WizardForm.StatusLabel.Caption;
      WizardForm.StatusLabel.Caption := 'Installing .NET framework...';
      WizardForm.ProgressGauge.Style := npbstMarquee;
      try
        { here put the .NET setup execution code }
      finally
        WizardForm.StatusLabel.Caption := StatusText;
        WizardForm.ProgressGauge.Style := npbstNormal;
      end;
    end;
    

    这是.NET安装程序执行期间向导表单的样子(进度条是动画的):

    在此输入图像描述

    2023-02-08 13:35 回答
  • 我只是想给@TLama添加一些内容:安装失败时关闭.这并不容易,因为WizardForm.Close;只需调用取消按钮即可被用户中止.最后,代码看起来像这样:

    [Code]
    var CancelWithoutPrompt: boolean;
    
    function InitializeSetup(): Boolean;
    begin
      CancelWithoutPrompt := false;
      result := true;
    end;
    
    procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
    begin
      if CurPageID=wpInstalling then
        Confirm := not CancelWithoutPrompt;
    end;
    
    function FrameworkIsNotInstalled: Boolean;
    begin
      Result := not RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full');
    end;
    
    procedure InstallFramework;
    var
      StatusText: string;
      ResultCode: Integer;
    begin
      StatusText := WizardForm.StatusLabel.Caption;
      WizardForm.StatusLabel.Caption := 'Installing .NET framework...';
      WizardForm.ProgressGauge.Style := npbstMarquee;
      try
          if not Exec(ExpandConstant('{tmp}\dotNetFx45_Full_asetup.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
      begin
        // you can interact with the user that the installation failed
        MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.',
          mbError, MB_OK);
        CancelWithoutPrompt := true;
        WizardForm.Close;       
      end;
      finally
        WizardForm.StatusLabel.Caption := StatusText;
        WizardForm.ProgressGauge.Style := npbstNormal;
      end;
    end;
    

    2023-02-08 13:35 回答
  • 检查.NET Framework 4.7只需2美分,适合@ Snicker的答案:

    function FrameworkIsNotInstalled: Boolean;
    var
      ver: Cardinal;
    begin
      Result :=
        not
        (
        (RegKeyExists(
          HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client')
        and
            RegQueryDWordValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client', 'Release', ver)
        )
        or
        (RegKeyExists(
          HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full')
        and
            RegQueryDWordValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', ver)
        )
        )
        and (ver < 460798)
    end;
    

    2023-02-08 13:35 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有