Inno Setup:验证是否安装了 .NET 4.0Inno Setup: Verify that .NET 4.0 is installed

Inno Setup: Verify that .NET 4.0 is installed

提问人:Mediator 提问时间:11/5/2010 最后编辑:Martin PrikrylMediator 更新时间:11/12/2021 访问量:48318

问:

我有一个需要 .NET 4.0 才能运行的组件,我的 Inno 安装程序如何验证它是否已安装,如果没有,则提示用户安装它?

.net inno-setup

评论


答:

90赞 Cody Gray - on strike 11/5/2010 #1

该函数在运行 Inno Setup 可执行文件时调用。为自定义脚本插入此代码应执行所需的操作:InitializeSetup

function IsDotNetDetected(version: string; service: cardinal): boolean;
// Indicates whether the specified version and service pack of the .NET Framework is installed.
//
// version -- Specify one of these strings for the required .NET Framework version:
//    'v1.1'          .NET Framework 1.1
//    'v2.0'          .NET Framework 2.0
//    'v3.0'          .NET Framework 3.0
//    'v3.5'          .NET Framework 3.5
//    'v4\Client'     .NET Framework 4.0 Client Profile
//    'v4\Full'       .NET Framework 4.0 Full Installation
//    'v4.5'          .NET Framework 4.5
//    'v4.5.1'        .NET Framework 4.5.1
//    'v4.5.2'        .NET Framework 4.5.2
//    'v4.6'          .NET Framework 4.6
//    'v4.6.1'        .NET Framework 4.6.1
//    'v4.6.2'        .NET Framework 4.6.2
//    'v4.7'          .NET Framework 4.7
//    'v4.7.1'        .NET Framework 4.7.1
//    'v4.7.2'        .NET Framework 4.7.2
//    'v4.8'          .NET Framework 4.8
//
// service -- Specify any non-negative integer for the required service pack level:
//    0               No service packs required
//    1, 2, etc.      Service pack 1, 2, etc. required
var
    key, versionKey: string;
    install, release, serviceCount, versionRelease: cardinal;
    success: boolean;
begin
    versionKey := version;
    versionRelease := 0;

    // .NET 1.1 and 2.0 embed release number in version key
    if version = 'v1.1' then begin
        versionKey := 'v1.1.4322';
    end else if version = 'v2.0' then begin
        versionKey := 'v2.0.50727';
    end

    // .NET 4.5 and newer install as update to .NET 4.0 Full
    else if Pos('v4.', version) = 1 then begin
        versionKey := 'v4\Full';
        case version of
          'v4.5':   versionRelease := 378389;
          'v4.5.1': versionRelease := 378675; // 378758 on Windows 8 and older
          'v4.5.2': versionRelease := 379893;
          'v4.6':   versionRelease := 393295; // 393297 on Windows 8.1 and older
          'v4.6.1': versionRelease := 394254; // 394271 before Win10 November Update
          'v4.6.2': versionRelease := 394802; // 394806 before Win10 Anniversary Update
          'v4.7':   versionRelease := 460798; // 460805 before Win10 Creators Update
          'v4.7.1': versionRelease := 461308; // 461310 before Win10 Fall Creators Update
          'v4.7.2': versionRelease := 461808; // 461814 before Win10 April 2018 Update
          'v4.8':   versionRelease := 528040; // 528049 before Win10 May 2019 Update
        end;
    end;

    // installation key group for all .NET versions
    key := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\' + versionKey;

    // .NET 3.0 uses value InstallSuccess in subkey Setup
    if Pos('v3.0', version) = 1 then begin
        success := RegQueryDWordValue(HKLM, key + '\Setup', 'InstallSuccess', install);
    end else begin
        success := RegQueryDWordValue(HKLM, key, 'Install', install);
    end;

    // .NET 4.0 and newer use value Servicing instead of SP
    if Pos('v4', version) = 1 then begin
        success := success and RegQueryDWordValue(HKLM, key, 'Servicing', serviceCount);
    end else begin
        success := success and RegQueryDWordValue(HKLM, key, 'SP', serviceCount);
    end;

    // .NET 4.5 and newer use additional value Release
    if versionRelease > 0 then begin
        success := success and RegQueryDWordValue(HKLM, key, 'Release', release);
        success := success and (release >= versionRelease);
    end;

    result := success and (install = 1) and (serviceCount >= service);
end;

function InitializeSetup(): Boolean;
begin
    if not IsDotNetDetected('v4.6', 0) then begin
        MsgBox('MyApp requires Microsoft .NET Framework 4.6.'#13#13
            'Please use Windows Update to install this version,'#13
            'and then re-run the MyApp setup program.', mbInformation, MB_OK);
        result := false;
    end else
        result := true;
end;

(代码取自此处:http://www.kynosarges.de/DotNetVersion.html)

首先,它检查是否存在指示已安装的 .NET Framework 版本的注册表项。如果注册表项不存在,它会提示用户下载 .NET Framework。如果用户说“是”,则打开下载 URL。(您可能需要将其在脚本中指定的版本更改为版本 4.0。


我还遇到了 [这篇关于 CodeProject 的文章][1],它可能是一种更全面和可定制的方式来完成您正在寻找的工作,尽管它可能需要更多的工作来理解,并且必须进行修改才能使用 4.0 版。

评论

0赞 Mediator 11/5/2010
好。但是我需要从本地(从我的安装应用程序)安装框架 4.0
0赞 Cody Gray - on strike 11/5/2010
您应该能够轻松修改上面的脚本来执行此操作。必须下载 .NET Framework 4.0 安装程序(“客户端配置文件”或“完整”,具体取决于应用需要),并将其包含在应用程序的安装介质中。然后,从脚本中,不要转到 Internet 获取安装程序,而是从安装源目录中打开现有的安装文件。或者只是显示一条消息,要求用户这样做(“请先运行”NetFWSetup.exe“应用程序)。
0赞 Mediator 11/5/2010
“请先运行”NetFWSetup.exe“应用程序” - 程序挖掘安装不是不做吗?
2赞 TLama 6/12/2012
对于那些想要在安装时安装框架的人(在您完成整个向导并运行安装过程之后),不要在事件中运行框架安装程序,当您运行安装向导时,它会立即开始安装框架,这对用户体验有什么问题。在部分中使用 Check 条件参数,如下所示。InitializeSetup[Run]
4赞 10/30/2012
作为上面引用的代码的作者,我想让你知道链接位置的代码已针对 .NET 4.5 进行了更新。
29赞 David Taylor 8/27/2013 #2

@Cody Gray - 感谢您的解决方案。很有帮助!

如果有人感兴趣,以下是我对他的函数的看法,使用枚举值而不是字符串。这种变化纯粹是个人喜好的问题。该代码包括 v4.5 的更改,并且根据我的有限测试似乎可以正常工作。

大卫

[Code]

//
// Enumeration used to specify a .NET framework version 
//
type TDotNetFramework = (
    DotNet_v11_4322,  // .NET Framework 1.1
    DotNet_v20_50727, // .NET Framework 2.0
    DotNet_v30,       // .NET Framework 3.0
    DotNet_v35,       // .NET Framework 3.5
    DotNet_v4_Client, // .NET Framework 4.0 Client Profile
    DotNet_v4_Full,   // .NET Framework 4.0 Full Installation
    DotNet_v45);      // .NET Framework 4.5

//
// Checks whether the specified .NET Framework version and service pack
// is installed (See: http://www.kynosarges.de/DotNetVersion.html)
//
// Parameters:
//   Version     - Required .NET Framework version
//   ServicePack - Required service pack level (0: None, 1: SP1, 2: SP2 etc.)
//
function IsDotNetInstalled(Version: TDotNetFramework; ServicePack: cardinal): boolean;
  var
    KeyName      : string;
    Check45      : boolean;
    Success      : boolean;
    InstallFlag  : cardinal; 
    ReleaseVer   : cardinal;
    ServiceCount : cardinal;
  begin
    // Registry path for the requested .NET Version
    KeyName := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\';

    case Version of
      DotNet_v11_4322:  KeyName := KeyName + 'v1.1.4322';
      DotNet_v20_50727: KeyName := KeyName + 'v2.0.50727';
      DotNet_v30:       KeyName := KeyName + 'v3.0';
      DotNet_v35:       KeyName := KeyName + 'v3.5';
      DotNet_v4_Client: KeyName := KeyName + 'v4\Client';
      DotNet_v4_Full:   KeyName := KeyName + 'v4\Full';
      DotNet_v45:       KeyName := KeyName + 'v4\Full';
    end;

    // .NET 3.0 uses "InstallSuccess" key in subkey Setup
    if (Version = DotNet_v30) then
      Success := RegQueryDWordValue(HKLM, KeyName + '\Setup', 'InstallSuccess', InstallFlag) else
      Success := RegQueryDWordValue(HKLM, KeyName, 'Install', InstallFlag);

    // .NET 4.0/4.5 uses "Servicing" key instead of "SP"
    if (Version = DotNet_v4_Client) or
       (Version = DotNet_v4_Full) or
       (Version = DotNet_v45) then
      Success := Success and RegQueryDWordValue(HKLM, KeyName, 'Servicing', ServiceCount) else
      Success := Success and RegQueryDWordValue(HKLM, KeyName, 'SP', ServiceCount);

    // .NET 4.5 is distinguished from .NET 4.0 by the Release key
    if (Version = DotNet_v45) then
      begin
        Success := Success and RegQueryDWordValue(HKLM, KeyName, 'Release', ReleaseVer);
        Success := Success and (ReleaseVer >= 378389);
      end;

    Result := Success and (InstallFlag = 1) and (ServiceCount >= ServicePack);
  end;

评论

0赞 vidriduch 2/4/2016
这看起来很棒,但您还会展示如何从检查参数中使用它吗?
0赞 Robert Koernke 2/19/2016
只需在上面的函数之后添加它: 然后在“检查”函数中调用它。function IsDotNetReallyInstalled(): Boolean; begin result := IsDotNetInstalled(DotNet_v45, 0); end;
0赞 Robert Koernke 2/19/2016
对不起。。。检查参数:添加“not”...不是 IsDotNetInstalled
0赞 vishnu 4/4/2017
你能告诉我检测 4.6.1 版本的注册表项名称吗?这样我就可以扩展你的代码了吗?谢谢
0赞 vishnu 4/4/2017
@David所以我已经为 4.6.1 版本扩展了您的代码,如果 (Version = DotNet_v4_6_1) 然后开始 Success := Success 和 RegQueryDWordValue(HKLM, KeyName, 'Release', ReleaseVer);成功 := 成功和 (ReleaseVer >= 394271);结束;但是我想知道最后一行的 InstallFlag 值 Result := Success 和 (InstallFlag = 1) 和 (ServiceCount >= ServicePack);如果传递给 version 为 DotNet_v4_6_1 的函数?因为它永远不会获得值,并且不会初始化。请问有什么意见吗?谢谢
4赞 Tobias81 12/3/2015 #3

如果你不在乎是否安装了 .NET 4 的“完整”或“客户端”版本:

try
  ExpandConstant('{dotnet40}');
  // Installed
except
  // Not installed
end;
4赞 Alberto Chiesa 12/4/2020 #4

感谢大家现有的解决方案,它们效果很好。

不过,我不需要支持每个框架版本,而是一次只支持一个,并且不需要“古老”版本(.NET 4.0 或更早版本)。我也不需要检查服务版本。

因此,代码变得简单多了,我发现降低噪音更可取:

[Code]
// http://www.kynosarges.de/DotNetVersion.html

function IsDotNetDetected(): boolean;
var
    key: string;
    install, release: cardinal;
    success: boolean;
begin
    key := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full'
    
    // success: true if the registry has been read successfully
    success := RegQueryDWordValue(HKLM, key, 'Install', install);
    success := success and RegQueryDWordValue(HKLM, key, 'Release', release);

    // install = 1 if framework is installed
    // 461808 -> .NET 4.7.2 461814 before Win10 April 2018 Update
    // see https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
    // for details
    result := success and (install = 1) and (release >= 461808);
end;

function InitializeSetup(): Boolean;
begin
    if not IsDotNetDetected() then begin
        MsgBox('MyApp requires Microsoft .NET Framework 4.7.2.'#13#13
            'Please install it and then re-run this setup program.', mbInformation, MB_OK);
        result := false;
    end else
        result := true;
end;

您只需在版本常量 () 上方的代码中替换为 Microsoft 参考页中所需的值,并相应地更新错误消息。461808

5赞 F. Weise 11/12/2021 #5

我发现至少从 innosetup 版本 6.0.5 开始,此功能一直是框架的一部分。因此,您不必自己编写函数代码。

功能:IsDotNetInstalled

下面是一个简短的示例:

[Setup]
AppName=".NET Framwork Test"
AppVersion=0.0.0.1
DefaultDirName={tmp}\MyApp

[Code]
function InitializeSetup(): Boolean;
begin
  Result := IsDotNetInstalled(net45, 0);

  if Result then begin
    MsgBox('Min .NET Framwork is installed', mbInformation, MB_OK);
  end else begin
    MsgBox('Min .NET Framwork is not installed', mbInformation, MB_OK);
  end;
end;

评论

0赞 Walter Verhoeven 5/10/2022
感谢您指出这一点,我刚刚查看了文档并注意到它似乎不支持 .net 6,您知道一种方便的测试方法吗?