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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20752882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:35:04  来源:igfitidea点击:

How can I install .NET framework as a prerequisite using Inno Setup?

.netinno-setup

提问by Wayne Werner

I have a question similar to Inno Setup: Verify that .NET 4.0 is installed, but it seems to be slightly different.

我有一个类似于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;

As you can see, I'm trying to register a file with the GAC. Unfortunately on some machines it's possible that the .NET framework is notinstalled. So I need to install it first. Is there anyway that I can force an installation of the .NET runtime beforeI try to register my files?

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

回答by TLama

Since the [Run]section is processed after the [Files]section, it is naturally impossible to do it with the script you've shown (hence your question). There are few ways where the one I would recommend is to execute the .NET setup from the AfterInstallparameter function of the setup entry itself. So you would remove your current [Run]section and write a script like this:

由于该[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;

The process is easy, if the Checkfunction of the .NET setup entry of the [Files]section evaluates to True (FrameworkIsNotInstalled), the entry is processed, which copies the setup binary into the Inno Setup's temporary folder and if that succeeds, the AfterInstallfunction InstallFrameworkis called immediately after. Inside of this function, the .NET setup is manually executed by calling Execfunction.

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

And finally, if all of that succeeds, the installation continues to process the next [Files]section entry, which is your assembly that is going to be registered. Now, with the installed .NET framework. So as you can see, the order of the [Files]section entries is crucial here.

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



You've additionally asked in your comment, how to show to the user some progress, since executing the .NET setup in the way I've posted here blocks the [Files]entry, which leads to showing the stopped progress bar and text about extracting files. Since it wouldn't be easy to get the .NET setup's installation progress, I would simply show to the user endless marquee progress bar during that setup execution.

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

To do this wrap that setup execution into a code like this:

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

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;

This is how the wizard form looks like during that .NET setup execution (the progress bar is animated):

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

enter image description here

在此处输入图片说明

回答by Snicker

I just want to add something to @TLama: The close when the setup fails. It's not so easy because WizardForm.Close;just invokes the cancel-button which can be aborted by the user. Finally, the code can look like that:

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

回答by BananaAcid

just my 2 cents on checking for .NET Framework 4.7, fits right in with @Snicker's answer:

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

回答by RandomEngy

You can also set it up to download the web bootstrapper and run it if you don't want to package in the very heavy full .NET installer. I have written a blog post on how to do that with Inno Download Plugin.

如果您不想在非常繁重的完整 .NET 安装程序中打包,您也可以将其设置为下载 Web 引导程序并运行它。我写了一篇关于如何使用 Inno Download Plugin 做到这一点的博客文章