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

Posted

技术标签:

【中文标题】如何使用 Inno Setup 安装 .NET 框架作为先决条件?【英文标题】:How can I install .NET framework as a prerequisite using Inno Setup? 【发布时间】:2014-01-12 05:21:46 【问题描述】:

我有一个类似于Inno Setup: Verify that .NET 4.0 is installed 的问题,但似乎略有不同。

[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 运行时

【问题讨论】:

InnoSetup: Verify that .NET 4.0 is installed的可能重复 @stuartd,它不是重复的... 绝对不是重复 - 只是检查,我已经在做。我正在分发可执行文件并希望在尝试将下一个文件安装到 GAC 之前安装它。 (这个问题也是我链接到的问题;) 注意正确的参数是/norestart而不是/noreboot @Marc.2377 为那些不阅读 cmets 的人更新了正确的参数 ;) 【参考方案1】:

由于[Run] 部分是在[Files] 部分之后处理的,因此使用您显示的脚本自然不可能做到这一点(因此您的问题)。我推荐的几种方法是从设置条目本身的AfterInstall 参数函数执行.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;

这个过程很简单,如果 [Files] 部分的 .NET 设置条目的 Check 函数评估为 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 设置执行期间向导表单的样子(进度条是动画的):

【讨论】:

史诗。这完全有效 - 但是有一个奇怪的地方 - 它似乎在执行安装时挂在“提取文件”上。有什么方法可以让用户知道这里确实发生了什么事? 我添加了一个代码框架,说明如何将安装进度条转换为选取框样式,并添加了关于在 .NET 安装执行期间安装 .NET 框架的文本。设置完成后,进度条变回正常样式,文本恢复为“正在提取文件...”。 我希望我能 +2 这个。这是一个很棒的解决方案! 我没有自己做 Marque,而是为 .NET 安装程序(也是 VC++ 运行时)使用了 /passive 选项。这确实有弹出额外消息框的缺点,但它是一个稍微简单的解决方案。 添加 /q 将再次导致安装失败,遗憾的是,非常感谢,我将删除 em【参考方案2】:

我只想向@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;

【讨论】:

Err,设置失败时关闭,在什么情况下?在哪里 ?主要是为什么?该问题没有询问安装失败时如何关闭向导表单。无论如何,强行关闭向导表单闻起来像是一个糟糕的 UX 想法。还是我错过了什么? 为什么?在您的代码中,即使框架安装失败,设置也会继续。不,他没有要求这样做,但如果它没有以“成功安装”结束并且用户无法执行程序,这是一个优势。不,它不会杀死安装程序。它只是将问题跳过给用户“你真的要取消吗”。 啊,我现在看到了问题。好吧,我可能应该建议从PrepareToInstall 事件安装,而不是使用AfterInstall 功能。这使您能够更优雅地退出设置。【参考方案3】:

检查 .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;

【讨论】:

你的功能很棒。如果有人在寻找其他版本的 .net,请查看此页面 docs.microsoft.com/en-us/dotnet/framework/migration-guide/… 正是我在寻找的东西,在几个小时内!非常感谢队友!注意,对于 4.7.1,最后一行应该是 and (ver 【参考方案4】:

如果您不想打包到非常繁重的完整 .NET 安装程序中,也可以将其设置为下载 Web 引导程序并运行它。我写了a blog post on how to do that with Inno Download Plugin。

【讨论】:

以上是关于如何使用 Inno Setup 安装 .NET 框架作为先决条件?的主要内容,如果未能解决你的问题,请参考以下文章

Inno Setup 如何使用皮肤插件更换软件安装包界面和外框包装?望详细解答!

Inno Setup:验证是不是安装了 .NET 4.0

Inno Setup CreateProcess 失败:代码 740(Inno Setup打包的程序提升为管理员权限)

inno setup检查dotnet core是不是已安装[关闭]

Inno Setup 如何读写文件

inno setup 如何定制安装最后一步