Более простая версия с использованием строкового ключа «Версия» и сравнения строк.
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
Недостаток: теоретически это может привести к ложному отрицанию, если установлено «v14.100.xy».Но результат будет только в том, что вы попытаетесь установить распространяемый пакет 14.16, который ничего не делает.
[Редактировать] Бонус-код: если вы создаете vswhere , вы можете использовать его для извлечения распространяемого пакетаиз установочного каталога Visual C ++:
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
Обратите внимание, что этот раздел не является обязательным, он условно включен с помощью теста, описанного ранее:
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