【问题标题】:Check for .NET4.5+ with NSIS使用 NSIS 检查 .NET4.5+
【发布时间】:2013-02-20 01:55:41
【问题描述】:

所有,我知道以下方法可以检查 NSIS 中的框架版本。对于 .NET4.0+,我目前使用

Function IsDotNetInstalled

    StrCpy $0 "0"
    StrCpy $1 "SOFTWARE\Microsoft\.NETFramework" ; Registry entry to look in.
    StrCpy $2 0

    StartEnum:
    ; Enumerate the versions installed.
    EnumRegKey $3 HKLM "$1\policy" $2

    ; If we don't find any versions installed, it's not here.
    StrCmp $3 "" noDotNet notEmpty

    ; We found something.
    notEmpty:
        ; Find out if the RegKey starts with 'v'.  
        ; If it doesn't, goto the next key.
        StrCpy $4 $3 1 0
        StrCmp $4 "v" +1 goNext
        StrCpy $4 $3 1 1

        ; It starts with 'v'.  Now check to see how the installed major version
        ; relates to our required major version.
        ; If it's equal check the minor version, if it's greater, 
        ; we found a good RegKey.
        IntCmp $4 ${DOT_MAJOR} +1 goNext yesDotNetReg
        ; Check the minor version.  If it's equal or greater to our requested 
        ; version then we're good.
        StrCpy $4 $3 1 3
        IntCmp $4 ${DOT_MINOR} yesDotNetReg goNext yesDotNetReg

    goNext:
        ; Go to the next RegKey.
        IntOp $2 $2 + 1
        goto StartEnum

    yesDotNetReg:
        ; Now that we've found a good RegKey, let's make sure it's actually
        ; installed by getting the install path and checking to see if the 
        ; mscorlib.dll exists.
        EnumRegValue $2 HKLM "$1\policy\$3" 0
        ; $2 should equal whatever comes after the major and minor versions 
        ; (ie, v1.1.4322)
        StrCmp $2 "" noDotNet
        ReadRegStr $4 HKLM $1 "InstallRoot"
        ; Hopefully the install root isn't empty.
        StrCmp $4 "" noDotNet
        ; Build the actuall directory path to mscorlib.dll.
        StrCpy $4 "$4$3.$2\mscorlib.dll"
        IfFileExists $4 yesDotNet noDotNet

    noDotNet:
        ; No, something went wrong along the way.  Looks like the 
        ; proper .NET Framework isn't installed.  
        MessageBox MB_ICONEXCLAMATION "To install UserCost, Microsoft's .NET Framework v${DOT_MAJOR}.${DOT_MINOR} \
        (or higher) must be installed. Cannot proceed with the installation!"
        ${OpenURL} "${WWW_MS_DOTNET4}"
        Abort

    yesDotNet:
        ; Everything checks out. Proceed with the rest of the installation.

FunctionEnd

这对 .NET4.0 非常有效,但我现在扩展了我的应用程序以利用 async/await 功能,随后需要用户安装 .NET4.5+。上述方法不适合,因为 .NET4.5 的安装现在不使用 regestry 路径“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\Policy”来存储任何新信息,即该路径似乎不包含.NET4.0 和 4.5 之间的变化。现在我看到了以下帖子:

NSIS Installer with .NET 4.5

它使用注册表路径/条目 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP' 进行检查。现在这也可以 bot 工作,因为条目不会从 .NET4.0 更改为 4.5。我注意到有一个名为 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\v4.0.30319\SKUs.NETFramework,Version=v4.5' 的条目,我可以用它来检查框架版本吗?

是否有使用 NSIS 检查 .NET4.5 的官方线路?

感谢您的宝贵时间。


注意:随后我的用户执行的一些 .NET4.5 安装具有注册表值

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full 

名为 Release 的 DWORD 值不是 378389 而是 378181。进行此更改似乎可以解决问题,因为 Release 的条目不在 .NET4.5 及更低版本的注册表中。

【问题讨论】:

    标签: .net installation nsis .net-4.5


    【解决方案1】:

    是的,有一种官方方法可以检查是否安装了 .NET Framework 4.5,即使它并不真正友好。来自MSDN

    您可以通过检查注册表中的 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full 子项中名为 DWORD 的值 Release 来测试是否安装了 .NET Framework 4.5 或 .NET Framework 4。此DWORD 的存在表明该计算机上已安装.NET Framework 4.5。 Release 的值是一个版本号。要确定是否安装了 .NET Framework 4.5 的最终发行版,请检查是否有等于或大于 378389 的值。

    http://msdn.microsoft.com/en-us/library/hh925568.aspx

    这意味着您首先必须检查是否安装了 4.0,然后检查 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full 中是否有一个名为 Release 的值,如果有,则表示已经安装了 4.5(我认为您可以跳过检查 pre -发布版本)。

    编辑:在此处查看this post 以了解有关检测较旧已安装 .NET 版本的详细信息,以及此MSDN article 以区分 4.5.x 版本。

    【讨论】:

    • 这是一个高质量的答案。 Microsoft 在哪里提供这些信息 - 或者我们应该自己找出来?感谢您的宝贵时间...
    • 我确实忘记引用source
    【解决方案2】:

    这是我编写的一个函数,用于检查并在需要时下载 .NET 4.5。此外,该代码还会查找 .NET 安装程序的本地副本——以防您将安装程序放在 CD 或 USB 驱动器或其他东西上。支持静默和非静默安装,以及设置重启标志。该函数是自包含的,但希望您包含 LogicLib(包含在基本 NSIS 安装中)。

    这是我为雷切尔的故事书的安装程序编写的代码。

    Function CheckAndDownloadDotNet45
    # Let's see if the user has the .NET Framework 4.5 installed on their system or not
    # Remember: you need Vista SP2 or 7 SP1.  It is built in to Windows 8, and not needed
    # In case you're wondering, running this code on Windows 8 will correctly return is_equal
    # or is_greater (maybe Microsoft releases .NET 4.5 SP1 for example)
    
    # Set up our Variables
    Var /GLOBAL dotNET45IsThere
    Var /GLOBAL dotNET_CMD_LINE
    Var /GLOBAL EXIT_CODE
    
    ReadRegDWORD $dotNET45IsThere HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" "Release"
    IntCmp $dotNET45IsThere 378389 is_equal is_less is_greater
    
    is_equal:
        Goto done_compare_not_needed
    is_greater:
        # Useful if, for example, Microsoft releases .NET 4.5 SP1
        # We want to be able to simply skip install since it's not
        # needed on this system
        Goto done_compare_not_needed
    is_less:
        Goto done_compare_needed
    
    done_compare_needed:
        #.NET Framework 4.5 install is *NEEDED*
    
        # Microsoft Download Center EXE:
        # Web Bootstrapper: http://go.microsoft.com/fwlink/?LinkId=225704
        # Full Download: http://go.microsoft.com/fwlink/?LinkId=225702
    
        # Setup looks for components\dotNET45Full.exe relative to the install EXE location
        # This allows the installer to be placed on a USB stick (for computers without internet connections)
        # If the .NET Framework 4.5 installer is *NOT* found, Setup will connect to Microsoft's website
        # and download it for you
    
        # Reboot Required with these Exit Codes:
        # 1641 or 3010
    
        # Command Line Switches:
        # /showrmui /passive /norestart
    
        # Silent Command Line Switches:
        # /q /norestart
    
    
        # Let's see if the user is doing a Silent install or not
        IfSilent is_quiet is_not_quiet
    
        is_quiet:
            StrCpy $dotNET_CMD_LINE "/q /norestart"
            Goto LookForLocalFile
        is_not_quiet:
            StrCpy $dotNET_CMD_LINE "/showrmui /passive /norestart"
            Goto LookForLocalFile
    
        LookForLocalFile:
            # Let's see if the user stored the Full Installer
            IfFileExists "$EXEPATH\components\dotNET45Full.exe" do_local_install do_network_install
    
            do_local_install:
                # .NET Framework found on the local disk.  Use this copy
    
                ExecWait '"$EXEPATH\components\dotNET45Full.exe" $dotNET_CMD_LINE' $EXIT_CODE
                Goto is_reboot_requested
    
            # Now, let's Download the .NET
            do_network_install:
    
                Var /GLOBAL dotNetDidDownload
                NSISdl::download "http://go.microsoft.com/fwlink/?LinkId=225704" "$TEMP\dotNET45Web.exe" $dotNetDidDownload
    
                StrCmp $dotNetDidDownload success fail
                success:
                    ExecWait '"$TEMP\dotNET45Web.exe" $dotNET_CMD_LINE' $EXIT_CODE
                    Goto is_reboot_requested
    
                fail:
                    MessageBox MB_OK|MB_ICONEXCLAMATION "Unable to download .NET Framework.  ${PRODUCT_NAME} will be installed, but will not function without the Framework!"
                    Goto done_dotNET_function
    
                # $EXIT_CODE contains the return codes.  1641 and 3010 means a Reboot has been requested
                is_reboot_requested:
                    ${If} $EXIT_CODE = 1641
                    ${OrIf} $EXIT_CODE = 3010
                        SetRebootFlag true
                    ${EndIf}
    
    done_compare_not_needed:
        # Done dotNET Install
        Goto done_dotNET_function
    
    #exit the function
    done_dotNET_function:
    
    FunctionEnd
    

    【讨论】:

    • 没问题。前几天我刚刚为自己写完这个函数,并通过 Twitter 偶然发现了这个页面并想“为什么不呢?”我喜欢您的代码,尽管我的代码没有提供 .NET 作为选项(因为程序需要它)。还有一点点允许 .NET 安装程序的本地副本运行,它允许将您的安装程序放在 CD 或 USB 密钥上。我注意到您的代码在 MessageBox 调用中没有使用 /SD(以允许静默操作 - 请随意查看我如何处理它)。
    • 这段代码有问题。 “未引用或从未设置的变量“dotNetDidDownload”。您应该在 NSISdl::download 调用之后从堆栈中弹出返回值,而不是将其作为参数提供。 StrCmp $dotNetDidDownload success fail 也应该是 StrCmp $dotNetDidDownload "success" success fail
    • 您可能应该提及参考页面以获取其他框架的编号,以便更多人使用。你上面的文章提到喜欢你的口味的人也需要参考。 docs.microsoft.com/en-us/dotnet/framework/migration-guide/…
    【解决方案3】:

    最后我使用了以下函数,它利用了上面的答案。此方法首先创建一个目录"$INSTDIR\dotNETFramework",其中包含 .NET Web 安装程序:

    Function CheckAndInstallDotNet
        ; Installer dotNetFx45_Full_setup.exe avalible from http://msdn.microsoft.com/en-us/library/5a4x27ek.aspx
        ; Magic numbers from http://msdn.microsoft.com/en-us/library/ee942965.aspx
        ClearErrors
        ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" "Release"
        IfErrors NotDetected
        ${If} $0 >= 378389
            DetailPrint "Microsoft .NET Framework 4.5 is installed ($0)"
        ${Else}
        NotDetected:
            MessageBox MB_YESNO|MB_ICONQUESTION ".NET Framework 4.5+ is required for ProgramX2013, \
                do you want to launch the web installer? This requires a valid internet connection." IDYES InstallDotNet IDNO Cancel 
            Cancel:
                MessageBox MB_ICONEXCLAMATION "To install ProgramX, Microsoft's .NET Framework v${DOT_MAJOR}.${DOT_MINOR} \
                    (or higher) must be installed. Cannot proceed with the installation!"
                ${OpenURL} "${WWW_MS_DOTNET4_5}"
                RMDir /r "$INSTDIR" 
                SetOutPath "$PROGRAMFILES"
                RMDir "$INSTDIR" 
                Abort
    
            ; Install .NET4.5.
            InstallDotNet:
                DetailPrint "Installing Microsoft .NET Framework 4.5"
                SetDetailsPrint listonly
                ExecWait '"$INSTDIR\dotNETFramework\dotNetFx45_Full_setup.exe" /passive /norestart' $0
                ${If} $0 == 3010 
                ${OrIf} $0 == 1641
                    DetailPrint "Microsoft .NET Framework 4.5 installer requested reboot."
                    SetRebootFlag true 
                ${EndIf}
                SetDetailsPrint lastused
                DetailPrint "Microsoft .NET Framework 4.5 installer returned $0"
        ${EndIf}
    
        ; Now remove the dotNETFramework directory and contents.
        RMDir /r "$INSTDIR\dotNETFramework" 
    FunctionEnd
    

    如果有 Internet 连接,此方法 seelessley 启动 .NET4.5 安装程序,并在安装完成后返回。

    我希望这对其他人有帮助。

    【讨论】:

    • @sa_ddam213 note 我刚刚收到客户通知,说他无法从 XP 自动运行 .NET Web 安装程序。我正在研究这个问题,并会在/如果我得到一个解决方案时发布一个解决方案......
    【解决方案4】:

    这是一个简单的 NSIS 函数,用于检查 .NET 版本(适用于 4.5、4.5.1、4.5.2 和 4.6)。数值比较基于MSDN

    将函数放在你的 NSIS 文件中并像这样调用它

    Call CheckForDotVersion45Up
    Pop $0
    DetailPrint $0
    

    这里是函数。

    ; returns a numeric value on the stack, ranging from 0 to 450, 451, 452 or 460. 0 means nothing found, the other values mean at least that version
    Function CheckForDotVersion45Up
    
      ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" Release
    
      IntCmp $0 393295 is46 isbelow46 is46
    
      isbelow46:
      IntCmp $0 379893 is452 isbelow452 is452
    
      isbelow452:
      IntCmp $0 378675 is451 isbelow451 is451
    
      isbelow451:
      IntCmp $0 378389 is45 isbelow45 is45
    
      isbelow45:
      Push 0
      Return
    
      is46:
      Push 460
      Return
    
      is452:
      Push 452
      Return
    
      is451:
      Push 451
      Return
    
      is45:
      Push 45
      Return
    
    FunctionEnd
    

    【讨论】:

      【解决方案5】:

      现在 .NET Framework 4.5.1 可用,需要检查注册表中名为 Release 的 DWORD 的实际值,而不仅仅是它的存在。

      值 378758 表示已安装 .NET Framework 4.5.1,但是,如 here 所述,此值在 Windows 8.1 上为 378675。

      【讨论】:

        【解决方案6】:

        如果您正在寻找 .net 框架 4.0+(及更高版本)的选项,包括

        • .net 4.5
        • .net 4.5.1

        您也可以查看此插件是否适用于 NSIS:DotNetChecker

        【讨论】:

        • @Killercam 感谢您的提醒。修好了。
        • 虽然 GitHub 项目很有用,但请注意默认情况下它会尝试下载缺少的框架版本。您的安装程序中可能不需要的东西。
        猜你喜欢
        • 2013-09-09
        • 1970-01-01
        • 2011-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-29
        相关资源
        最近更新 更多