有时当我做一个小项目时,我不够小心,不小心添加了一个我不知道的DLL依赖项。当我将这个程序发送给朋友或其他人时,“它不工作”,因为“一些DLL”丢失了。这当然是因为程序可以在我的系统上找到DLL,但不能在他们的系统上找到。
是否有一种方法来扫描可执行文件的DLL依赖项或在“干净”的DLL自由环境中执行程序进行测试,以防止这些糟糕的情况?
有时当我做一个小项目时,我不够小心,不小心添加了一个我不知道的DLL依赖项。当我将这个程序发送给朋友或其他人时,“它不工作”,因为“一些DLL”丢失了。这当然是因为程序可以在我的系统上找到DLL,但不能在他们的系统上找到。
是否有一种方法来扫描可执行文件的DLL依赖项或在“干净”的DLL自由环境中执行程序进行测试,以防止这些糟糕的情况?
最安全的事情是有一些干净的虚拟机,你可以在上面测试你的程序。在您希望测试的每个版本上,将VM恢复到其初始干净值。然后使用它的设置安装你的程序,看看它是否工作。
Dll问题有不同的面貌。如果你使用Visual Studio并动态链接到CRT,你必须分发CRT dll。更新你的VS,你必须分发另一个版本的CRT。仅仅检查依赖关系是不够的,因为你可能会错过这些。在我看来,在一台干净的机器上完全安装是唯一安全的解决方案。
如果您不想设置一个完整的测试环境并使用Windows 7,您可以使用XP-Mode作为初始的清理机器,并使用XP-More来复制VM。
In the past (i.e. WinXP days), I used to depend/rely on DLL Dependency Walker (depends.exe) but there are times when I am still not able to determine the DLL issue(s). Ideally, we'd like to find out before runtime by inspections but if that does not resolve it (or taking too much time), you can try enabling the "loader snap" as described on http://blogs.msdn.com/b/junfeng/archive/2006/11/20/debugging-loadlibrary-failures.aspx and https://msdn.microsoft.com/en-us/library/windows/hardware/ff556886(v=vs.85).aspx and briefly mentioned LoadLibrary fails; GetLastError no help
警告:我过去一直在用gflag搞砸我的窗户,让它爬到它的膝盖,你已经被预先警告过了。
注意:“Loader snap”是每进程的,所以UI enable不会一直检查(使用cdb或glfags -i)
在您的开发机器上,您可以执行该程序并运行Sysinternals Process Explorer。在下面的窗格中,它将显示加载的dll和它们的当前路径,这很方便,原因有很多。如果你正在执行你的部署包,它会显示哪些dll被引用在错误的路径(即没有正确打包)。
目前,我们公司使用Visual Studio Installer项目来遍历依赖树,并将其输出为程序的松散文件。在VS2013中,这现在是一个扩展:https://visualstudiogallery.msdn.microsoft.com/9abe329c-9bba-44a1-be59-0fbf6151054d。然后,我们将这些松散的文件打包到一个更全面的安装程序中,但至少该安装程序将所有的dot net依赖项放在一个位置,并在东西丢失时警告你。
我可以为Linux粉丝推荐有趣的解决方案。在探索了这个解决方案之后,我已经从DependencyWalker切换到这个。
你可以使用你喜欢的ldd而不是windows相关的exe, dll。
要做到这一点,你需要在Windows上安装Cygwin(基本安装,不需要额外的软件包),然后启动Cygwin终端。现在你可以运行你最喜欢的Linux命令,包括:
$ ldd your_dll_file.dll
UPD:你也可以在Windows上通过git bash终端使用ldd。如果已经安装了git,则不需要安装cygwin。
Jesse已经提到了NDepend(如果你分析。net代码的话),但是让我们来解释一下它是如何帮助你的。
是否有一个程序/脚本,可以扫描可执行DLL 依赖或在“干净的”无dll环境中执行程序 为了防止这些糟糕的情况?
在NDepend项目属性面板中,你可以定义要分析的应用程序集(绿色),NDepend将推断应用程序使用的第三方程序集(蓝色)。提供了用于搜索应用程序和第三方程序集的目录列表。
如果在这些目录中没有找到第三方程序集,则该程序集将处于错误模式。例如,如果我删除。net Fx目录C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319,我可以看到。net Fx第三方程序集没有被解析:
免责声明:我为NDepend工作
找出要使用的程序集的完整文件路径 按下开始按钮,输入“dev”。启动名为“VS 2017开发者命令提示符”的程序 在打开的窗口中,键入dumpbin / dependencies [path],其中[path]是在步骤1中计算出的路径 按回车键
嘭,你得到了你的依赖信息。窗口应该是这样的:
VS 2019更新:在你的VS安装中需要这个包:
请参考SysInternal工具包从微软下面的链接, https://learn.microsoft.com/en-us/sysinternals/downloads/process-explorer
进入下载文件夹,以管理员权限打开Procexp64.exe。 打开查找菜单->“查找句柄或DLL”选项或Ctrl+F快捷方式。
DLL是在“调试模式”下编译然后部署的吗?
如果是这样,它可能依赖于dll的“D”版本。例如:
MSVCP140D.dll
VCRUNTIME140D.dll
如果DLL是在“发布模式”下构建的,这些将不是依赖项。D版本不附带Microsoft Visual c++ Redistributables。
事实是否如此,正如其他人指出的那样:
从Visual Studio:工具-> Visual Studio命令提示符。
在命令提示符中对DLL运行dumpbin / dependencies。
尝试依赖,它被描述为“一个开源的现代依赖步行者”。
它有一个GUI,但它也可以从可选JSON输出的命令行工作!
递归显示mydll.dll在深度为1之前的依赖项:
Dependencies.exe -chain mydll.dll -depth 1
输出示例:
□ mydll.dll (ROOT) : C:/.../mydll.dll
| □ USER32.dll (WellKnownDlls) : C:\WINDOWS\SysWOW64\user32.dll
| □ ADVAPI32.dll (WellKnownDlls) : C:\WINDOWS\SysWOW64\advapi32.dll
| □ ole32.dll (WellKnownDlls) : C:\WINDOWS\SysWOW64\ole32.dll
| □ GDI32.dll (WellKnownDlls) : C:\WINDOWS\SysWOW64\gdi32.dll
| □ CRYPT32.dll (WellKnownDlls) : C:\WINDOWS\SysWOW64\CRYPT32.dll
| □ Secur32.dll (WindowsFolder) : C:\WINDOWS\SysWOW64\Secur32.dll
| □ MSVCP140D.dll (WindowsFolder) : C:\WINDOWS\SysWOW64\MSVCP140D.dll
| □ USP10.dll (WindowsFolder) : C:\WINDOWS\SysWOW64\USP10.dll
| □ KERNEL32.dll (WellKnownDlls) : C:\WINDOWS\SysWOW64\kernel32.dll
| □ VCRUNTIME140D.dll (WindowsFolder) : C:\WINDOWS\SysWOW64\VCRUNTIME140D.dll
| □ ucrtbased.dll (WindowsFolder) : C:\WINDOWS\SysWOW64\ucrtbased.dll
注意,如果最大依赖深度很深,可能需要很长时间才能产生结果。
要查看Windows中的“。dll”依赖项和其他有用信息-我可以强烈推荐CFF资源管理器(https://ntcore.com/?page_id=388),它是免费的,非常有用。您可以查看“。dll”文件和许多其他函数的“导入”和“导出”依赖项。而且它有一个GUI -所以你不必使用cli…