Есть ли способ проверить заранее, если Windows EXE не удастся загрузить из-за отсутствия DLL?

Если вы попытаетесь установить распространяемый vs2015 на Windows 8.1 без каких-либо обновлений, он не будет установлен. Но в процессе установки будет достаточно далеко, чтобы guid был в реестре, поэтому, если вы запустите программу, которая проверяет наличие распространяемого в реестре, вы пройдете эту проверку.

Если вы затем попытаетесь запустить программу, скомпилированную с vs2015, для которой требуются некоторые библиотеки DLL, которые не удалось установить, вы получите всплывающее окно, которое говорит: «Программа не может быть запущена, потому что …».

Я работаю над установщиком (с NSIS), который имеет эту проблему, и я пытаюсь найти способ обнаружить отсутствующую проблему DLL, прежде чем я запустите .exe и получить всплывающее окно. Есть ли какой-нибудь инструмент командной строки, который я могу запустить, или какая-либо функция NSIS, которую я могу вызвать, которая укажет мне на проблему до того, как это произойдет?

Или даже способ проверить, правильно ли установлен распространяемый vs2015? (без необходимости проверять наличие каждого отдельного файла в распространяемой программе, потому что я не знаю, чем они все являются.)

Ищите какие-либо идеи для решения общей проблемы, не обязательно специально проходить эту проверку. Я ожидаю, что могут быть разные способы распространения распространяемого файла.

1

Решение

Я полагаю, что VS2015 является одной из версий, которая устанавливает .DLL в System32 без WinSxS, так что вы можете просто проверить, если vcruntime140.dll & msvcp140.dll находится в $SysDir,

Если вы беспокоитесь о том, что это может быть частичная установка, вы можете посмотреть, сможете ли вы загрузить ее (при условии, что ваш установщик соответствует размеру того, что вы устанавливаете):

!include LogicLib.nsh
System::Call 'KERNEL32::LoadLibrary(t "$SysDir\msvcr100.dll")p.r0'
${If} $0 P<> 0
DetailPrint "I was able to load the MSVC 2010 run-time DLL"${Else}
DetailPrint "Ooops"${EndIf}

Это может считаться хаком, но этого может быть достаточно для ваших нужд. Зависимость Уокер скажет вам, какие библиотеки искать.

Вы также можете позвонить MsiGetProductInfo с NSIS, если вы хотите:

!define MSVC2005_X86REDIST_PRODUCTCODE {A49F249F-0C91-497F-86DF-B2585E8E76B7}
!define MSVC2008_X86REDIST_PRODUCTCODE {FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}
!define MSVC2010_X86REDIST_PRODUCTCODE {196BB40D-1578-3D01-B289-BEFC77A11A1E}
!define MSVC2010SP1_X86REDIST_PRODUCTCODE {F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}
!define MSVC2010_AMD64REDIST_PRODUCTCODE {DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}
!define MSVC2010SP1_AMD64REDIST_PRODUCTCODE {1D8E6291-B0D5-35EC-8441-6616F567A0F7}

!define MSVCREDIST_PRODUCTCODE ${MSVC2010_X86REDIST_PRODUCTCODE} ; I don't have VS2015 redist installed on this machine so I could not test it.
!include LogicLib.nsh
System::Call 'MSI::MsiGetProductInfo(t "${MSVCREDIST_PRODUCTCODE}", t "ProductName", t"?"r1, *i${NSIS_MAX_STRLEN})i.r0'
${If} $0 == 0
DetailPrint "ProductName: $1"System::Call 'MSI::MsiGetProductInfo(t "${MSVCREDIST_PRODUCTCODE}", t "AssignmentType", t"?"r1, *i${NSIS_MAX_STRLEN})i.r0'
DetailPrint "AssignmentType: $1"System::Call 'MSI::MsiGetProductInfo(t "${MSVCREDIST_PRODUCTCODE}", t "PackageCode", t"?"r1, *i${NSIS_MAX_STRLEN})i.r0'
DetailPrint "PackageCode: $1"System::Call 'MSI::MsiGetProductInfo(t "${MSVCREDIST_PRODUCTCODE}", t "VersionString", t"?"r1, *i${NSIS_MAX_STRLEN})i.r0'
DetailPrint "VersionString: $1"${Else}
DetailPrint "Not registered with Windows Installer"${EndIf}

Этот пост в блоге говорит, что Visual Studio 2005 использует MsiQueryProductState и это, вероятно, хорошая простая альтернатива, если вам не нужно больше деталей:

!define INSTALLSTATE_DEFAULT 5
System::Call 'MSI::MsiQueryProductState(t "${MSVCREDIST_PRODUCTCODE}")i.r0'
${If} ${INSTALLSTATE_DEFAULT} = $0
DetailPrint "Installed"${Else}
DetailPrint "Not installed"${EndIf}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]