2013-03-05 55 views
11

所有的,我知道以下方法檢查NSIS中的框架版本。對於.NET4.0 +我目前使用使用NSIS檢查.NET4.5 +

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 \微軟\ NET Framework安裝\ NDP」做檢查。現在,這也是機器人的工作,因爲入口不會從.NET4.0更改爲4.5。我注意到有和稱爲'HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 \ SKUs.NETFramework,版本= 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及更低版本的註冊表中。

回答

23

是的,有來檢查是否安裝了.NET Framework 4.5的官方方式,即使它不是真正友好。從MSDN

您可以測試是否在.NET Framework 4.5或.NET Framework 4是通過檢查註冊表中的子項HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full名爲Release一個DWORD值安裝。此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(我認爲您可以跳過對預發佈版本的檢查)。

編輯:檢查this post這裏SO有關檢測舊的安裝.NET版本,這對於MSDN article版本4.5.x區分細節。

+0

這是一個高質量的答案。這些信息在哪裏由微軟提供 - 或者我們是否期望找到自己的信息?感謝您的時間... – MoonKnight 2013-03-05 15:42:03

+1

我忘了引用[源代碼](http://msdn.microsoft.com/en-us/library/hh925568.aspx)。 – 2013-03-05 15:44:47

+0

剛剛找到它。再次感謝... – MoonKnight 2013-03-05 15:49:20

5

這是我編寫的一個函數,用於檢查並下載.NET 4.5。此外,代碼還會查找.NET安裝程序的本地副本 - 以防將安裝程序放到CD或USB驅動器或其他設備上。支持無提示安裝和非安靜安裝,以及設置Reboot標誌。該函數是自包含的,但希望包含LogicLib(包含在基本的NSIS安裝中)。

這是我爲我的Rachel故事書的安裝程序編寫的代碼。

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 
+0

感謝您的代碼。我會發布我最後一起去... – MoonKnight 2013-03-07 09:03:56

+1

沒問題。我剛剛完成了爲自己寫的功能,並通過Twitter偶然發現了這個頁面,並指出「爲什麼不呢?」我喜歡你的代碼,儘管我沒有將.NET作爲一個選項(因爲程序需要它)。還有一點允許.NET安裝程序的本地副本運行,這樣您的安裝程序就可以放置在CD或USB密鑰上。我注意到你的代碼沒有在你的MessageBox調用中使用/ SD(以允許靜默操作 - 請隨時查看我如何處理它)。 – 2013-03-08 00:17:07

+0

此代碼存在問題。 「變量」dotNetDidDownload「未引用或從未設置」。您應該在NSISdl :: download調用之後從堆棧中彈出返回值,而不是將其作爲參數提供。同時'StrCmp $ dotNetDidDownload失敗成功'應該是'StrCmp $ dotNetDidDownload「成功」成功失敗「。 – fretje 2015-03-02 18:20:11

4

最後,我去了以下函數,它利用了上面的答案。該方法首先創建一個目錄"$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 

這種方法seemlessley啓動.NET4.5安裝程序,如果有互聯網連接,並返回在安裝完成後。

我希望這可以幫助別人。

+1

+1,謝謝,正是我在找的東西。 – 2013-09-05 11:09:34

+0

@ sa_ddam213 note我剛剛收到客戶端通知,他說他在XP中自動運行.NET Web安裝程序時遇到了問題。我正在研究此問題,並會在/如果我得到一個解決方案時發佈解決方案... – MoonKnight 2013-09-05 13:28:05

+0

請參閱http://stackoverflow.com/questions/11027185/net-4-5-rc-framework-clr-windows-xp-compatibility 。 – MoonKnight 2013-09-05 15:01:17

1

既然.NET Framework 4.5.1可用,則需要檢查註冊表中名爲Release的DWORD的實際值,而不僅僅是它的存在。

值爲378758表示安裝了.NET Framework 4.5.1,但是,如在Windows 8.1上的here這個值爲378675。

0

如果您正在尋找與.NET框架選項4.0+(及以上),包括

  • .NET 4.5
  • .NET 4.5.1

你也可以檢查此插件NSIS:DotNetChecker

+0

鏈接被破壞... – MoonKnight 2014-10-08 09:42:48

+0

@Killercam謝謝你的擡頭。修復。 – Mehrad 2014-10-08 10:05:06

2

這是一個簡單的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