NSIS code to check for at least Windows 10 and X64 - nsis

I've added a .OnInit function to my installer script:
Function .onInit
${IfNot} ${AtLeastWin10}
MessageBox mb_iconStop "Windows 10 x64 is required to install DeepSkyStacker 5.1.0"
Abort
${EndIf}
${IfNot} ${RunningX64}
MessageBox mb_iconStop "Windows 10 x64 is required to install DeepSkyStacker 5.1.0"
Abort
${EndIf}
FunctionEnd
Can the two tests be combined? It seems a bit clumsy as it is ...
Thanks
David

Looks like:
Function .onInit
${IfNot} ${AtLeastWin10}
${OrIfNot} ${RunningX64}
MessageBox mb_iconStop "Windows 10 x64 is required to install DeepSkyStacker 5.1.0"
Abort
${EndIf}
FunctionEnd
Should do it!

Related

Knowing in a Section if another Section has already been executed

I want to create a Suite installer for the various application we develop. The structure is as follows:
Application A
Requires no driver installation
Application B
Requires driver 1 and 2
Application C
Requires driver 2 and 3
The user has the option to install any application he wants, or multiple. I know how to use Sections for this. This will work fine if the user selects only Application A, or Application A with either B or C. However, if the user selects Application B and C, I would like to avoid that driver 2 will be prompted to install twice.
Is there a way to achieve this? For instance, is it possible to know when the section for Application C is executed, that the section for Application B has already been executed, and that driver 2 does not need to be installed again?
There are probably many ways to handle this, one is to put the driver in a hidden section that you make sure is in the correct state:
!include LogicLib.nsh
!include Sections.nsh
!include x64.nsh
Page Components
Page Directory
Page InstFiles
Section "-Driver2" SID_DRIVER2
${If} ${IsNativeAMD64}
; Install AMD64 64-bit driver/library
${ElseIf} ${IsNativeARM64}
; Install ARM64 64-bit driver/library
${ElseIf} ${IsNativeIA32}
; Install i386 32-bit driver/library
${Else}
Abort "Unsupported CPU architecture!"
${EndIf}
SectionEnd
Section "App B" SID_APPB
SectionEnd
Section /o "App C" SID_APPC
SectionEnd
Function .onSelChange
${If} ${SectionIsSelected} ${SID_APPB}
${OrIf} ${SectionIsSelected} ${SID_APPC}
!insertmacro SelectSection ${SID_DRIVER2}
${Else}
!insertmacro UnselectSection ${SID_DRIVER2}
${EndIf}
FunctionEnd
Function .onInit
Call .onSelChange ; Make sure things are configured correctly in silent installers
FunctionEnd

Is there any way that we can read the registry version number key in a generic way using NSIS?

Using NSIS when installing the newer version of the software, from specific older version no (for eg., 3.01.00) i am upgrading it to the newer version automatically by uninstalling the older version and installing newer version like as shown below:
Note: Here my older version of the software installer is using WIX and the newer installer is using NULLSOFT
ReadRegStr $R1 HKLM "SOFTWARE\Millinnium\3.01.00" "InstallPath"
ReadRegStr $R2 HKLM "SOFTWARE\Millinnium\3.02.00" "InstallPath"
${If} $R1 != ""
MessageBox MB_YESNO|MB_ICONQUESTION "$(UninstallPrevVer)" IDYES noUninstOld
Abort
noUninstOld:
ExecWait '"MsiExec.exe" /X{8ED262EE-FC73-47A9-BB86-D92223246881} /qb!'
${ElseIf} $R2 != ""
MessageBox MB_YESNO|MB_ICONQUESTION "$(UninstallPrevVer)" IDYES noUninstOld
Abort
noUninstOld:
ExecWait '"MsiExec.exe" /X{8ED262EE-FC73-47A9-BB86-D92223246881} /qb!'
${EndIf}
But if i have much older versions for eg., <3.01.00 (i.e., 3.0 or 3.0.0.1 or 2.0 or lesser) I wanted to display a generic message displayed stating to uninstall the existing version manually before installing the newer version.
Is there any way that we can read the registry version number key in a generic way?
or do i need to follow for each version like as shown below?
ReadRegStr $R1 HKLM "SOFTWARE\Millinnium\3.0" "InstallPath"
ReadRegStr $R2 HKLM "SOFTWARE\Millinnium\3.0.0.1" "InstallPath"
ReadRegStr $R2 HKLM "SOFTWARE\Millinnium\2.0" "InstallPath"
Use EnumRegKey to enumerate keys:
Section
StrCpy $0 0
loop:
EnumRegKey $1 HKLM "SOFTWARE\Millinnium" $0
StrCmp $1 "" done
IntOp $0 $0 + 1
DetailPrint "Key: $1"
Goto loop
done:
SectionEnd
SectionEnd

NSIS If Else statement with x64 header throwing macro error

when I was looking for an answer to how to find out if a Windows OS was 32bit or 64bit, I stumbled upon this other answer: Use NSIS to install 32bit... and used this code below.
!include x64.nsh
Function .onInit
#Determine the bitness of the OS and enable the correct section
${If} ${RunningX64}
SectionSetFlags ${SEC0000} ${SECTION_OFF}
SectionSetFlags ${SEC0001} ${SF_SELECTED}
${Else}
SectionSetFlags ${SEC0001} ${SECTION_OFF}
SectionSetFlags ${SEC0000} ${SF_SELECTED}
${EndIf}
FunctionEnd
However, I run into this error:
!insertmacro: If
!insertmacro: macro named "_LOGICLIB_TEMP" not found!
Error in macro _RunningX64 on macroline 1
Error in macro If on macroline 5
I'm not sure what that's all about. I figured it might have been something to do with LogicLib.nsh, but I am using the exact same if, else statements else where in the same script and no issues there. So, it leads me to believe that its the x64.nsh library that is stopping me.
I have never seen this error before. Your current code should work unless you happen to define LOGICLIB somewhere in your code before you include x64.nsh and/or LogicLib.nsh.
Try putting this at the top of your .nsi:
!ifdef LOGICLIB
!warning "LOGICLIB should not be defined here"
!undef LOGICLIB
!endif
!include LogicLib.nsh
!ifmacrondef _LOGICLIB_TEMP
!error "Corrupted LogicLib.nsh?"
!endif
!include x64.nsh

Uninstall old version before installing new

I am new to NSIS, however I want to make checkup of existing installed older versions while installing the new one. I made this exactly like I found here - http://nsis.sourceforge.net/Auto-uninstall_old_before_installing_new But because I need to check were the old version is installed to make uninstallation correctly, I added InstallLocation registry value to the installation progress.
If I use ExecWait '$R0 _?=$INSTDIR' and the installation folder of the old version is the same as INSTDIR, everything works perfectly. But if I use ExecWait '$R0 _?=$R1' it gives me NSIS installer error, but I just can't find where is the problem, what have I done wrong?
Can someone help please?
Thanks
Registry is added by this:
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${AppName}" "InstallLocation" '"$INSTDIR"'
The code of function:
ReadRegStr $R0 HKLM \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${AppName}" \
"UninstallString"
StrCmp $R0 "" done
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
"${AppName} is already installed. $\n$\nClick OK to remove the \
previous version or Cancel to cancel the installation." \
IDOK uninst
Abort
;Run the uninstaller
uninst:
ReadRegStr $R1 HKLM \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${AppName}" \
"InstallLocation"
ClearErrors
HideWindow
ClearErrors
ExecWait '$R0 _?=$R1'
BringToFront
done:
functionEnd
You are writing the InstallLocation path with quotes, don't do that or strip off the quotes in your code before executing the installer...

Installing VC++ Redist 2008 in silent mode

I want to install VC++ Redist 2008 in my NSIS setup script. I got the following piece of script to do it:
; Test if Visual Studio Redistributables 2005+ SP1 installed
; Returns -1 if there is no VC redistributables intstalled
Function CheckVCRedist
Push $R0
ClearErrors
ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{7299052b-02a4-4627-81f2-1818da5d550d}" "Version"
; if VS 2005+ redist SP1 not installed, install it
IfErrors 0 VSRedistInstalled
StrCpy $R0 "-1"
VSRedistInstalled:
Exch $R0
FunctionEnd
Basically its for VC++ Redist 2005, but i've edited the reg settings to check for presence of 2008(is it ok to do so?). I need the piece of script/command to install the VC++ Redist 2008.
where do i store the VC setup and how to execute in silent mode.
Is it ok to check at .onInit?
Could someone please give a complete script which checks for presence and how to execute it in silent mode.
Thanks,
Well I am not much sure about how to check for if vcredist is already installed from registry.
What I do for my installer is, to check for a particular dll file in the system which the vcredist installs (and for which I am installing vcredist). So if that file is present in my $WinDir I assume vcredist is already installed otherwise I download & install(silently) the vcredist.
Following is my script which may be of some help to you:
ifFileExists $Windir\System32\mfc100.dll +2 0
StrCpy $IsMfcInstalled "no"
${If} $IsMfcInstalled == "no"
download1:
NSISdl::download "http://download.microsoft.com/download/5/B/C/5BC5DBB3-652D-4DCE-B14A-475AB85EEF6E/vcredist_x86.exe" "$Temp/vcredist_x86.exe"
pop $0
StrCmp "$0" "success" execStep1 instAbort1
execStep1:
Execwait '"$Temp/vcredist_x86.exe" /q' ; '/q' to install silently
pop $0
StrCmp "$0" "success" done execStep1
instAbort1:
StrCmp $0 "cancel" 0 +1
MessageBox MB_OKCANCEL "Connection Timed Out. Retry ? " IDOK download1 IDCANCEL 0
Quit
${else}
goto done
${endIf}
done:

Resources