2013-03-05 11 views
11

Alle, ich kenne die folgenden Methoden, um die Framework-Version in NSIS zu überprüfen. Für .NET4.0 + zur Zeit ichNach .NET4.5 + mit NSIS suchen

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 

verwenden sehr gut Dies funktioniert für .NET4.0, aber ich habe jetzt meine Anwendung erweitert die async/await Funktionen zu nutzen und anschließend müssen die Benutzer .NET4.5 installieren +. Die obige Methode ist nicht geeignet, da die Installation für .NET 4.5 jetzt nicht den Registrierungspfad "HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ Policy" verwendet, um neue Informationen zu speichern, das heißt, dieser Pfad scheint keinen Wert zu enthalten Änderungen zwischen .NET4.0 und 4,5 Jetzt habe ich die folgenden Beiträge zu sehen.

NSIS Installer with .NET 4.5

, die den Registrierungspfad/Eintrag 'HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ NET Framework Setup \ NDP' verwendet, um die Kontrollen zu tun Jetzt funktioniert das auch, da sich der Eintrag nicht von .NET4 auf 4.5 ändert Ich bemerke, dass es einen Eintrag namens 'HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 \ SKUs.NETFramework, Version = v4 gibt. 5 'kann ich dies verwenden, um die Framework-Version ausnahmslos zu überprüfen?

Gibt es eine offizielle Möglichkeit, nach .NET4 mit NSIS zu suchen?

Danke für Ihre Zeit.


Hinweis: anschließend einige Installation von .NET4.5 meine Benutzer haben mussten auf Registry-Werte durchgeführt

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

ein DWORD-Wert mit dem Namen Release war nicht 378389 aber 378181. Diese Änderung schien das Problem zu lösen, da der Eintrag für Release nicht in der Registrierung für .NET4.5 und niedriger ist.

Antwort

23

Ja, es ist eine offizielle Art und Weise zu überprüfen, ob .NET Framework 4.5 installiert ist, auch wenn es nicht wirklich freundlich ist. Von MSDN:

können Sie testen, ob das .NET Framework 4.5 oder .NET Framework 4 durch Prüfen des HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full Unterschlüssel in der Registrierung für einen Wert DWORDRelease genannt installiert ist. Die Existenz dieser zeigt an, dass das .NET Framework 4.5 auf diesem Computer installiert wurde. Der Wert von Release ist eine Versionsnummer. Um festzustellen, ob die endgültige Version des .NET Framework 4.5 installiert ist, überprüfen Sie für einen Wert, der gleich oder größer als 378389.

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

Es heißt, Sie müssen zunächst prüfen, ob 4.0 ist installiert und dann zu überprüfen, ob es einen Wert mit dem Namen Release in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full gibt, wenn ja, dann ist 4,5 bereits installiert (ich denke, Sie können die Überprüfung für eine Vorabversion überspringen).

EDIT: Check this post hier auf SO Einzelheiten über ältere installierte .NET-Versionen zu erfassen und diese MSDN article zwischen für 4.5.x Versionen zu unterscheiden.

+0

Das ist eine Qualitätsantwort. Wo werden diese Informationen von Microsoft zur Verfügung gestellt - oder sollen wir selbst herausfinden? Danke für Ihre Zeit ... – MoonKnight

+1

Ich habe vergessen, die [Quelle] (http://msdn.microsoft.com/en-us/library/hh925568.aspx) zu verweisen. –

+0

Ich habe es gerade gefunden. Danke nochmal ... – MoonKnight

5

Hier ist eine Funktion, die ich geschrieben, die überprüft und bei Bedarf heruntergeladen wird, .NET 4.5. Darüber hinaus sucht der Code auch nach einer lokalen Kopie des .NET-Installationsprogramms - für den Fall, dass Sie Ihr Installationsprogramm auf eine CD oder ein USB-Laufwerk oder etwas anderes stellen. Unterstützt Silent und Non-Silent-Installationen sowie das Setzen des Reboot-Flags. Die Funktion ist eigenständig, erwartet jedoch, dass Sie LogicLib (das in der grundlegenden NSIS-Installation enthalten ist) enthalten.

Dies ist der Code, den ich für den Installer für meine Rachel's Story Bücher geschrieben habe.

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

Danke für den Code. Ich werde posten, womit ich am Ende auch gegangen bin ... – MoonKnight

+1

Kein Problem. Ich habe gerade neulich die Funktion für mich selbst fertig geschrieben und bin über Twitter auf diese Seite gestolpert und habe mir gedacht "warum nicht?" Ich mag Ihren Code, obwohl meiner .NET nicht als eine Option darstellt (da das Programm es erfordert). Es gibt auch ein kleines Stück, das die Ausführung einer lokalen Kopie des .NET-Installationsprogramms ermöglicht, mit der Sie Ihr Installationsprogramm auf eine CD oder einen USB-Stick legen können. Ich habe festgestellt, dass Ihr Code in Ihren MessageBox-Aufrufen nicht/SD verwendet (um unbeaufsichtigte Operationen zu ermöglichen - schauen Sie ruhig, wie ich damit umgehe). –

+0

Es gibt ein Problem mit diesem Code. "Variable" dotNetDidDownload "nicht referenziert oder nie gesetzt".Sie sollten den Rückgabewert nach dem Aufruf von NSISdl :: download aus dem Stapel auffüllen, anstatt ihn als Parameter anzugeben. Außerdem sollte 'StrCmp $ dotNetDidDownloadDownload erfolgreich fehlschlagen'' StrCmp $ dotNetDidDownload 'Erfolg "Erfolg fehlgeschlagen" sein. – fretje

4

Am Ende ging ich mit der folgenden Funktion, die die obige Antwort verwendet. Diese Methode erstellt zuerst ein Verzeichnis "$INSTDIR\dotNETFramework", die den .NET Web-Installer enthält:

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 

Diese Methode seemlessley startet das .NET4.5 Installateur, wenn eine Internet-Verbindung und kehrt ist, nachdem die Installation abgeschlossen ist.

Ich hoffe, das hilft jemand anderem.

+1

+1, Danke, genau das, was ich gesucht habe. –

+0

@ sa_ddam213 Hinweis Ich habe gerade dieses zweite eine Kundenmitteilung erhalten, die sagt, dass er Probleme mit dem Ausführen des .NET Web Installers automatisch von XP hat. Ich schaue mir das an und werde eine Lösung veröffentlichen, wenn/wenn ich einen bekomme ... – MoonKnight

+0

Siehe http://stackoverflow.com/questions/11027185/net-4-5-rc-framework-clr-windows-xp-compatibility . – MoonKnight

1

Jetzt, da .NET Framework 4.5.1 verfügbar ist, muss der tatsächliche Wert von DWORD namens "Release" in der Registrierung überprüft werden, nicht nur dessen Existenz.

Ein Wert von 378758 bedeutet, dass .NET Framework 4.5.1 installiert ist, jedoch wie beschrieben here dieser Wert ist 378675 unter Windows 8.1.

0

Wenn Sie sich für Optionen mit .NET Framework 4.0 oder höher (und höher) einschließlich

  • .net 4.5
  • .net 4.5.1

Sie auch diese Suche überprüfen Plug-In für NSIS: DotNetChecker

+0

Link ist kaputt ... – MoonKnight

+0

@Killercam Danke für die Köpfe hoch. Behoben. – Mehrad

2

Hier ist eine einfache NSIS-Funktion, die für .NET-Versionen überprüft (funktioniert für 4.5, 4.5.1, 4.5.2 und 4.6). Die numerischen Vergleiche basieren auf MSDN.

Legen Sie die Funktion in der NSIS-Datei und rufen Sie es wie so

Call CheckForDotVersion45Up 
Pop $0 
DetailPrint $0 

ist die Funktion.

; 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