Как проверить, что распространяемый Visual C ++ 2017 x86 установлен или не используется NSIS - PullRequest
0 голосов
/ 27 января 2019

Перед установкой программного обеспечения мне необходимо проверить, установлен Visual C++ 2017 redistributable(x86) или нет.Если он не установлен, при первой установке программного обеспечения я могу установить распространяемый исполняемый файл.

Когда я установил его вручную, он отображается по следующему пути:

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

Пожалуйста, помогите мне какчтобы проверить вышеуказанный путь, используя NSIS?

, чтобы, если исполняемый файл отсутствует перед установкой программного обеспечения, я мог установить его с кодом ниже:

!insertmacro MUI_LANGUAGE "English"

Section "MyApp"

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

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

Ответы [ 3 ]

0 голосов
/ 30 января 2019

Также правильный (и рекомендованный многими разработчиками) способ - просто установить среду выполнения без вывода сообщений.

Это не повредит никаким компонентам или программному обеспечению, и это намного быстрее и проще.

0 голосов
/ 08 апреля 2019

Более простая версия с использованием строкового ключа «Версия» и сравнения строк.

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  
0 голосов
/ 27 января 2019
!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

но я не знаю, является ли это лучшим способом обнаружения распространяемого ПО, поскольку вы проверяете определенную вспомогательную версию и неизвестный GUID.

В документации говоритсячто вы должны проверить HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ VisualStudio \% vs-версия% \ 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
...