13

总而言之,我知道以下方法可以检查 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 的安装现在不使用记录路径“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\Policy”来存储任何新信息,即该路径似乎不包含一个值.NET4.0 和 4.5 之间的变化。现在我看到了以下帖子:

带有 .NET 4.5 的 NSIS 安装程序

它使用注册表路径/条目 '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 

一个名为Releasewas not 378389but的 DWORD 值378181。进行此更改似乎可以解决问题,Release因为 .NET4.5 及更低版本的注册表中没有条目。

4

6 回答 6

25

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

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

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

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

编辑:在 SO 上查看这篇文章以获取有关检测较早安装的 .NET 版本的详细信息,以及这篇MSDN 文章以区分 4.5.x 版本。

于 2013-03-05T15:35:09.017 回答
5

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

这是我为我的 Rachel's Story 书籍的安装程序编写的代码。

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
于 2013-03-07T02:15:59.170 回答
5

最后,我使用了以下函数,它利用了上面的答案。此方法首先创建一个"$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 安装程序,并在安装完成后返回。

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

于 2013-03-07T09:07:26.707 回答
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
于 2015-10-27T11:21:46.030 回答
1

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

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

于 2013-12-12T09:29:37.767 回答
1

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

  • .net 4.5
  • .net 4.5.1

您还可以检查此插件是否适用于 NSIS:DotNetChecker

于 2014-10-07T01:49:39.953 回答