bhavya
bhavya

Reputation: 73

How to check Visual C++ 2017 redistributable x86 is installed or not using NSIS

Before installing the software, I need to check if the Visual C++ 2017 redistributable(x86) is installed or not. If it is not installed, while installing the software first I can install the redistributable executable.

When i installed it manually it is showing in the below path:

Computer\HKEY_CLASSES_ROOT\Installer\Dependencies\VC,redist.x86,x86,14.16,bundle\Dependents\{67f67547-9693-4937-aa13-56e296bd40f6}

Please help me how to check the above path using NSIS?

So that If the executable is not present before installing the software i can install it with the below code:

!insertmacro MUI_LANGUAGE "English"

Section "MyApp"

SetOutPath $INSTDIR
File "\Desktop\Common\vcredist_x86.exe"

ExecShell "" "$INSTDIR\vcredist_x86.exe"
SectionEnd

Upvotes: 5

Views: 4678

Answers (3)

Anders
Anders

Reputation: 101756

!include LogicLib.nsh

!macro _RegKeyExistsIn _key _pack _t _f
#DBG: DetailPrint '${_key} ${_pack}'
!insertmacro _LOGICLIB_TEMP
!ifndef _RegKeyExistsIn_var
    !define _RegKeyExistsIn_var
    Var /Global _RegKeyExistsIn
!endif
StrCpy $_RegKeyExistsIn 0
SetErrors
EnumRegKey $_LOGICLIB_TEMP ${_pack} $_RegKeyExistsIn
    IntOp $_RegKeyExistsIn $_RegKeyExistsIn + 1
    StrCmp $_LOGICLIB_TEMP "" +3
    StrCmp $_LOGICLIB_TEMP "${_key}" "" -3
    ClearErrors
IfErrors `${_f}` `${_t}`
!macroend

Section
${If} "Dependents{67f67547-9693-4937-aa13-56e296bd40f6}" RegKeyExistsIn 'HKCR "Installer\Dependencies\VC,redist.x86,x86,14.16,bundle"'
    DetailPrint "Found the key"
${Else}
    DetailPrint "Key does not exist"
${EndIf}
SectionEnd

but I don't know if this is the best way to detect the redistributable because you are checking a specific minor version and some unknown GUID.

The documentation says that you should check HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\%vs-version%\VC\Runtimes\{x86|x64|ARM}
old documentation

!include LogicLib.nsh

!ifmacrondef _VerCheck2=>
!macro _VerCheck2_geq_imp l1 l2 r1 r2 _t _f
!insertmacro _LOGICLIB_TEMP
!define _VerCheck2_geq_imp _VerCheck2_geq_${__COUNTER__}
StrCpy $_LOGICLIB_TEMP 0
IntCmpU ${l1} ${r1} ${_VerCheck2_geq_imp}eq "" ${_VerCheck2_geq_imp}end
StrCpy $_LOGICLIB_TEMP 1
Goto ${_VerCheck2_geq_imp}end
${_VerCheck2_geq_imp}eq:
IntCmpU ${l2} ${r2} ${_VerCheck2_geq_imp}end "" ${_VerCheck2_geq_imp}end
StrCpy $_LOGICLIB_TEMP 1
${_VerCheck2_geq_imp}end:
!undef _VerCheck2_geq_imp
!insertmacro _= $_LOGICLIB_TEMP 0 `${_f}` `${_t}`
!macroend
!macro _VerCheck2=> _lhs _rhs _t _f
!insertmacro _VerCheck2_geq_imp ${_lhs} ${_rhs} `${_f}` `${_t}`
!macroend
!endif

Section
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "Installed"
ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "Major"
ReadRegDWORD $2 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "Minor"
${If} $0 <> 0
    DetailPrint "Found version $1.$2"
    ${If} "$1 $2" VerCheck2=> "14 16"
        DetailPrint "The installed version is usable"
    ${Else}
        DetailPrint "Must install redist"
    ${EndIf}
${Else}
    DetailPrint "Must install redist"
${EndIf}
SectionEnd

Upvotes: 2

MSalters
MSalters

Reputation: 180050

Simpler version, using the "Version" string key and a string comparison.

Section "CheckVCRedist"
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "Version"
DetailPrint "Found version $0"
; Check for 14.16.27027 [sic]
${If} $0 >= "v14.16.27024.01"
   DetailPrint "The installed version is usable"
${Else}
   DetailPrint "Must install redist"
${EndIf}
SectionEnd

Downside: this could theoretically give a false negative if "v14.100.x.y" is installed. But the impact would only be that you try to install the 14.16 redistributable, which does nothing.

[Edit] Bonus code: If you build vswhere, you can use it to extract the redistributable from your Visual C++ install directory:

Section /o VCRedist VCRedist_id
    ; Use the "pluginsdir"; it's really the NSIS temp dir, and it's cleaned up at the end.
    InitPluginsDir
    SetOutPath "$pluginsdir" 

    ; Finding the correct redistributable is a bit of a problem. MSVC itself ships with an
    ; appropriate redistributable. It's location will likely be similar to
    ; C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Redist\MSVC\14.16.27012
    ; but the exact location of the Redist folder can differ. That's why vswhere.exe is used.
    ; Note that the vswhere used is the local one, NOT the one from
    ; Visual Studio itself (finding that would be a chicken-and-egg problem). This version
    ; is new enough to support the -find parameter, which is what we need to find the
    ; redistributable. Stuff the result in a temporary redist.path file.
    !system 'vswhere.exe -latest -find "VC/Redist/**/vc_redist.x64.exe" > redist.path' 
    !define /file REDISTPATH redist.path
    ; Check what version we found. This is used to decide at install time whether we need to
    ; unpack this redistributable.
    !getdllversion "${REDISTPATH}" RedistVer
    !echo "Including VC++ Redistributable Version ${RedistVer1}.${RedistVer2}.${RedistVer3}.${RedistVer4}"

    SetCompress off
    File "${REDISTPATH}"
    SetCompress auto

    ; Cleanup the temporary redist.path file which held the output of vswhere -find
    !system 'del redist.path'

    ExecWait "vc_redist.x64.exe"
SectionEnd

Note that the section is optional, it's conditionally enabled using the test detailed before:

Function VCRedistNeeded
    SetRegView 64 
    ReadRegStr $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Version"
    DetailPrint "Found version $0"
    ${If} $0 >= "v${RedistVer1}.${RedistVer2}.${RedistVer3}.${RedistVer4}"
       DetailPrint "VC++ redistributable already present"
    ${Else}
      DetailPrint "Installing VC++ redistributable."
      SectionSetFlags ${VCRedist_id} 1 ; Selected
    ${EndIf}
FunctionEnd  

Upvotes: 2

Slappy
Slappy

Reputation: 5472

The also correct (and by many developers recommended) way is to simply install the Runtime silently.

It will not harm any components or software and it is much quicker and easier.

Upvotes: 0

Related Questions