How to insure a required version of .NETFramework is installed
From NSIS Wiki
| Author: John J. Pike (talk, contrib) |
Contents |
[edit] Description
This function allows you to select a minimum version of the .NETFrame work be installed. If it or a higher version is not present the function will abort the installation.
[edit] The Function
; Usage ; Define in your script two constants: ; DOT_MAJOR "(Major framework version)" ; DOT_MINOR "{Minor frameword version)" ; ; Call IsDotNetInstalled ; This function will abort the installation if the required version ; or higher version of the .NETFramework is not installed. Place it in ; either your .onInit function or your first install section before ; other code. 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: ;Nope, something went wrong along the way. Looks like the ;proper .NETFramework isn't installed. MessageBox MB_OK "You must have v${DOT_MAJOR}.${DOT_MINOR} or greater of the .NETFramework installed. Aborting!" Abort yesDotNet: ;Everything checks out. Go on with the rest of the installation. FunctionEnd
I hope this is helpful.
[edit] Description
Hi John,
thanks for writing this function, I've used it in my installer. However I did a slight modification to it, because I needed to recognize minor version as well (e.g. 2.0.50727), because our project does not work with .NET 2.0 beta which differs only in the last number. Here is the code:
[edit] The Function
; Usage ; Define in your script two constants: ; DOT_MAJOR "(Major framework version)" ; DOT_MINOR "{Minor framework version)" ; DOT_MINOR_MINOR "{Minor framework version - last number after the second dot)" ; ; Call IsDotNetInstalledAdv ; This function will abort the installation if the required version ; or higher version of the .NETFramework is not installed. Place it in ; either your .onInit function or your first install section before ; other code. Function IsDotNetInstalledAdv Push $0 Push $1 Push $2 Push $3 Push $4 Push $5 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} +1 goNext yesDotNetReg ;detect sub-version - e.g. 2.0.50727 ;takes a value of the registry subkey - it contains the small version number EnumRegValue $5 HKLM "$1\policy\$3" 0 IntCmpU $5 ${DOT_MINOR_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: ;Nope, something went wrong along the way. Looks like the ;proper .NETFramework isn't installed. ;Uncomment the following line to make this function throw a message box right away ; MessageBox MB_OK "You must have v${DOT_MAJOR}.${DOT_MINOR}.${DOT_MINOR_MINOR} or greater of the .NETFramework installed. Aborting!" ; Abort StrCpy $0 0 Goto done yesDotNet: ;Everything checks out. Go on with the rest of the installation. StrCpy $0 1 done: Pop $4 Pop $3 Pop $2 Pop $1 Exch $0 FunctionEnd
[edit] Macro Conversion
Hello lads, I was very pleased with this function. However, copying constantly "IsDotNetInstalled" or "IsDotNetInstalledAdv" (or even saving them to a .nsh file) may be a bother to some people. As well, I did this just to make your script more organized, sense-full, and well, I was bored.
Instead, create a new file into your "NSISDirectory\Includes" folder, and name it "DotNetSearch.nsh"
Open it for editing, and copy all the code below then save it. (simple ZIP download may be available soon, however I do not often do this as I like users to see the code they are copying)
!macro DotNetSearch DOTNETVMAJOR DOTNETVMINOR DOTNETVMINORMINOR DOTNETLASTFUNCTION DOTNETPATH Var /GLOBAL DOTNET1 Var /GLOBAL DOTNET2 Var /GLOBAL DOTNET3 Var /GLOBAL DOTNET4 Var /GLOBAL DOTNET5 Var /GLOBAL DOTNET6 Push $DOTNET1 Push $DOTNET2 Push $DOTNET3 Push $DOTNET4 Push $DOTNET5 Push $DOTNET6 StrCpy $DOTNET1 "0" StrCpy $DOTNET2 "SOFTWARE\Microsoft\.NETFramework" StrCpy $DOTNET3 0 DotNetStartEnum: EnumRegKey $DOTNET4 HKLM "$DOTNET2\policy" $DOTNET3 StrCmp $DOTNET4 "" noDotNet dotNetFound dotNetFound: StrCpy $DOTNET5 $DOTNET4 1 0 StrCmp $DOTNET5 "v" +1 goNextDotNet StrCpy $DOTNET5 $DOTNET4 1 1 IntCmp $DOTNET5 ${DOTNETVMAJOR} +1 goNextDotNet yesDotNetReg StrCpy $DOTNET5 $DOTNET4 1 3 IntCmp $DOTNET5 ${DOTNETVMINOR} +1 goNextDotNet yesDotNetReg StrCmp ${DOTNETVMINORMINOR} "" +1 yesDotNetReg IntCmpU $DOTNET5 ${DOTNETVMINORMINOR} yesDotNetReg goNextDotNet yesDotNetReg goNextDotNet: IntOp $DOTNET3 $DOTNET3 + 1 Goto DotNetStartEnum yesDotNetReg: EnumRegValue $DOTNET3 HKLM "$DOTNET2\policy\$DOTNET4" 0 StrCmp $DOTNET3 "" noDotNet ReadRegStr $DOTNET5 HKLM $DOTNET2 "InstallRoot" StrCmp $DOTNET5 "" noDotNet StrCpy $DOTNET5 "$DOTNET5$DOTNET4.$DOTNET3\mscorlib.dll" IfFileExists $DOTNET5 yesDotNet noDotNet noDotNet: StrCmp ${DOTNETLASTFUNCTION} "INSTALL_ABORT" +1 nDN2 MessageBox MB_YESNO|MB_ICONQUESTION \ "You must have Microsoft .NETFramework version ${DOTNETVMAJOR}.${DOTNETVMINOR}.${DOTNETVMINORMINOR}$\nor higher installed. Install now?" \ IDYES +2 IDNO +1 Abort ExecWait '${DOTNETPATH}' Goto DotNetStartEnum nDN2: StrCmp ${DOTNETLASTFUNCTION} "INSTALL_NOABORT" +1 nDN3 MessageBox MB_YESNO|MB_ICONQUESTION \ "Microsoft .NETFramework version ${DOTNETVMAJOR}.${DOTNETVMINOR}.${DOTNETVMINORMINOR} is not installed.$\nDo so now?" \ IDYES +1 IDNO +3 ExecWait '${DOTNETPATH}' Goto DotNetStartEnum StrCpy $DOTNET1 0 Goto DotNetFinish nDN3: StrCmp ${DOTNETLASTFUNCTION} "WARNING" +1 nDN4 MessageBox MB_OK|MB_ICONEXCLAMATION \ "Warning:$\n$\n$\t$\tMicrosoft .NETFramework version$\n$\t$\t${DOTNETVMAJOR}.${DOTNETVMINOR}.${DOTNETVMINORMINOR} is not installed!" \ IDOK 0 StrCpy $DOTNET1 0 Goto DotNetFinish nDN4: StrCmp ${DOTNETLASTFUNCTION} "ABORT" +1 nDN5 MessageBox MB_OK|MB_ICONEXCLAMATION \ "Error:$\n$\n$\t$\tMicrosoft .NETFramework version$\n$\t$\t${DOTNETVMAJOR}.${DOTNETVMINOR}.${DOTNETVMINORMINOR} is not installed, aborting!" \ IDOK 0 Abort nDN5: StrCmp ${DOTNETLASTFUNCTION} "IGNORE" +1 nDN6 StrCpy $DOTNET1 0 Goto DotNetFinish nDN6: MessageBox MB_OK \ "$(^Name) Setup internal error.$\nMacro 'DotNetSearch', parameter '4'(${DOTNETLASTFUNCTION})invalid.$\nValue must be INSTALL_ABORT|INSTALL_NOABORT|WARNING|ABORT|IGNORE$\nSorry for the inconvienence.$\n$\tAborting..." \ IDOK 0 Abort yesDotNet: StrCpy $DOTNET1 1 DotNetFinish: Pop $DOTNET6 Pop $DOTNET5 Pop $DOTNET4 Pop $DOTNET3 Pop $DOTNET2 !define ${DOTNETOUTCOME} $DOTNET1 Exch $DOTNET1 !macroend
This macro is just a slightly edited (for easier use as a macro, user choices, and avoiding possible conflictions). It was actually edited off of "DotNetSearchAdv" and was made able to have the following capabilities pointed out below.
[edit] Using the Macro
When using the DotNetSearch macro, there are 5 simple parameters that will be explained. Parameter 1 is the Major version of the required .NETFramework. Parameter 2 is the Minor version of the required .NetFramework. Parameter 3 is the Secondary Minor version of the required .NetFramework. Keep in mind, the DotNetSearch macro must be used within a function/section. (In Example:)
Function .onInit !instertmacro 2 0 50727 "" "" FunctionEnd ;or Function .onInit !insertmacro 2 0 "" "" "" FunctionEnd
Parameter 4 defines what happens if the required version of .NETFramework is not found. There are 5 different options:
- INSTALL_ABORT
- Shows a message box asking whether or not to install .NETFramework (pressing no aborts setup)
- INSTALL_NOABORT
- Shows a message box asking whether or not to install .NETFramework (pressing no continues setup without installing .NetFramework)
- WARNING
- Shows a message box warning the user that they do not have the required .NETFramework version, then after clicking OK, simply continues the setup.
- ABORT
- Shows a message box informing the user that they do not have the required .NETFramework version, then after clicking OK, aborts the setup.
- IGNORE
- Ignore continues the setup even if the required version of .NETFramework version is not installed, without warning, aborting, or installing.
Parameter 5 defines the location that the executable file to install .NETFramework is. This is so that if the file is external, it can be called upon. If it's not, then you can try other tricks to install it. Perhaps defining parameter 4 as IGNORE, then telling your setup to extract the setup file from your setup file to a temporary folder (IE: $TEMP) then installing, or finding a way to install from online. However, this macro does not support online installing, and I do not plan on modifying it too. But, I am very open to anyone modifying the code, in-fact, the result of whether or not .NETFramework is installed is saved to ;;${DOTNETOUTCOME}, so if you wish to include code after the macro depending on whether it is installed (${DOTNETOUTCOME} will equal 0) or whether it is (${DOTNETOUTCOME} will equal 1), you can. Using this you could probably easily instert your own message box or download .NETFramework online.
Yet again, that is you burden.

