Avant d'installer le logiciel, je dois vérifier si le Visual C++ 2017 redistributable(x86) est installé ou non. S'il n'est pas installé, en installant d'abord le logiciel, je peux installer l'exécutable redistribuable.

Lorsque je l'ai installé manuellement, il s'affiche dans le chemin ci-dessous:

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

Veuillez m'aider à vérifier le chemin ci-dessus en utilisant NSIS?

Pour que si l'exécutable n'est pas présent avant d'installer le logiciel, je puisse l'installer avec le code ci-dessous:

!insertmacro MUI_LANGUAGE "English"

Section "MyApp"

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

ExecShell "" "$INSTDIR\vcredist_x86.exe"
SectionEnd
2
bhavya 27 janv. 2019 à 19:17

3 réponses

Meilleure réponse
!include LogicLib.nsh

!macro _RegKeyExistsIn _key _pack _t _f
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

Mais je ne sais pas si c'est la meilleure façon de détecter le redistribuable parce que vous vérifiez une version mineure spécifique et un GUID inconnu.

La documentation dit que vous devriez vérifier HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ VisualStudio \% vs-version% \ VC \ Runtimes \% x86 | x64 | ARM%:

!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
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" "MajorVersion"
ReadRegDWORD $2 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "MinorVersion"
${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
0
Anders 28 janv. 2019 à 18:19

La méthode également correcte (et recommandée par de nombreux développeurs) consiste simplement à installer le Runtime en silence.

Cela n'endommagera aucun composant ou logiciel et c'est beaucoup plus rapide et plus facile.

0
Slappy 30 janv. 2019 à 19:02

Version plus simple, utilisant la clé de chaîne "Version" et une comparaison de chaînes.

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

Inconvénient: cela pourrait théoriquement donner un faux négatif si "v14.100.x.y" est installé. Mais l'impact serait seulement que vous essayez d'installer le redistribuable 14.16, ce qui ne fait rien.

[Éditer] Code bonus: si vous créez vswhere, vous pouvez l'utiliser pour extraire le redistribuable de votre répertoire d'installation 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

Notez que la section est facultative, elle est activée conditionnellement à l'aide du test détaillé précédemment:

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  
1
MSalters 5 août 2019 à 13:06