有没有一种方法可以预先测试Windows exe是否由于缺少dll而无法加载? [英] Is there a way to test beforehand if a windows exe will fail to load because of missing dlls?

查看:231
本文介绍了有没有一种方法可以预先测试Windows exe是否由于缺少dll而无法加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您尝试在Windows 8.1上安装vs2015可再发行组件而不进行任何更新,则它将无法安装.但这将使guid进入注册表的安装过程将足够多,因此,如果您运行一个程序来检查注册表中是否存在可再发行组件,那么您将获得通过该检查的机会.

If you try and install the vs2015 redistributable on windows 8.1 without any updates, it will fail to install. But it will get far enough into the install process that the guid is in the registry so if you run a program that checks for the existence of the redistributable in the registry, you'll get past that check.

如果您随后尝试运行用vs2015编译的程序,该程序要求某些无法安装的dll,您将看到一个弹出窗口,提示该程序无法启动,因为...",您就会知道演练.

If you then try and run a program compiled with vs2015 that requires some of the dlls that failed to install, you'll get a popup that says "The program can't start because..." you know the drill.

我正在开发一个存在此问题的安装程序(使用NSIS),并且我试图找到一种方法来检测dll丢失问题,然后再运行.exe并获取弹出窗口.有没有可以运行的命令行工具或可以调用的任何NSIS函数,可以在发生此问题之前为我提供线索?

I'm working on an installer (with NSIS) that is having this problem, and I'm trying to find a way to detect the dll missing problem before I run the .exe and get the popup. Is there any command line tool I can run or any NSIS function I can call that will clue me into this problem before it happens?

或者甚至是一种检查vs2015可再发行文件是否正确安装的方法? (不必检查可再分发文件中每个文件的存在,因为我不知道它们都是什么.)

Or even a way to check if the vs2015 redistributable installed correctly? (without having to check for the existence of every single file in the redistributable, because I don't know what they all are.)

寻找解决整体问题的想法,但不一定要通过这项检查.我希望可以有各种各样的方法来重新安装可分发文件.

Looking for any ideas to solve the overall problem, not necessarily to specifically get past this one check. I expect there can be all sorts of ways the redistributable can fail to install.

推荐答案

我相信VS2015是在不使用WinSxS的情况下在System32中安装.DLL的版本之一,因此您也许可以只检查vcruntime140.dll& msvcp140.dll在$SysDir中.

I believe VS2015 is one of the versions that installs the .DLLs in System32 without WinSxS so you could perhaps just check if vcruntime140.dll & msvcp140.dll is in $SysDir.

如果您担心它可能是部分安装,则可以查看是否可以加载它(假设您的安装程序与您要安装的东西的位数相符):

If you are worried that it might be a partial install you could see if you can load it (assuming your installer matches the bitness of the thing you are installing):

!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}

这可能被认为有点骇人听闻,但它可能足以满足您的需求. Dependency Walker 会告诉您要查找哪些DLL.

This might be considered a bit of a hack but it might be enough for your needs. Dependency Walker will tell you which DLLs to look for.

如果愿意,还可以使用NSIS呼叫MsiGetProductInfo:

You can also call MsiGetProductInfo with NSIS if you wish:

!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}

This blog post says that Visual Studio 2005 uses MsiQueryProductState and that is probably a nice simple alternative if you don't need any more details:

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

这篇关于有没有一种方法可以预先测试Windows exe是否由于缺少dll而无法加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆