如何检测应用程序所需的DLL文件?

10
简而言之:我想做与“Dependency Walker”相同的事情。
是否有任何Win32 API函数可以枚举EXE和/或DLL文件的依赖项?
而且,是否有安全的方法来检测ActiveX类的依赖关系?(我怀疑这是不可能的,但谁知道呢...)
编辑:我知道有可用的工具提供相同的核心功能(Dependency Walker、ProcessExplorer、AQTime等),但我想创建自己的程序,它会转储包含所需模块的文本文件。

你可能需要考虑修改你的问题标题。如果你想知道如何通过Win32 API实现,你应该在标题中明确说明。这不仅仅是纠结于细节;其他人以后也可能会尝试寻找相同的信息,而你的标题可以告诉他们你的问题是否涉及此问题。 - Onorio Catenacci
即便如此,您仍需注意,如果需要确保所有使用的文件都被记录,可能需要执行应用程序的所有功能。 - Kris Kumler
7个回答

9
以下命令将列出 some.exe 的直接依赖项:
dumpbin /imports some.exe

它也适用于DLL。

这不会列出诸如在应用程序启动时通过LoadLibrary调用加载的插件等依赖项。对于COM依赖关系,情况也是如此(就我所知)。

如果您需要知道运行中程序使用的所有DLL,请使用ProcessExplorer。


1
可以通过打开VS 201x的开发人员命令提示符来执行dumpbin。这可以从Windows按钮访问,向下滚动到Visual Studio 201x文件夹。 - Richard Jessop

4

启动应用程序,并确保 Process Explorer 已经运行,并设置过滤器以筛选你的应用程序 .exe 名称。

没有办法在不运行可执行文件的情况下检测所有 COM 依赖项。


4

使用findstr -i .dll exe.exe | more | findstr -i .dll | more命令可以查找exe.exe文件中的所有.dll文件。

注释:)


1
完全是胡说八道,会产生假阳性和假阴性。会为包含“*.dll”字符串的依赖项报告,而不确定该字符串在哪里使用。无法考虑在运行时加载的DLL(例如通过调用LoadLibrary或实例化ActiveX控件时)。 - IInspectable
这个答案的想法过于幼稚... 一个简单的搜索就能轻易地击溃它。 - kayleeFrye_onDeck

2
看起来,Dependency Walker源代码本身是通过MSJ由Microsoft提供的。请查看Re:[DUG]:Dependency Walker
您需要参考其他网站进行下载,因为此邮件中给出的链接无法使用。
请检查MSJ Source Code Updates:由于我没有时间,我没有检查它是否包含源代码或仅包含EXE文件。

1
你的第一个链接已经失效了,而第二个链接只是指向一个可执行文件。在stackoverflow上,仅提供链接的回答是不被鼓励的。 - David Grayson

2

用户@blue...提到了Dependency Walker。使用Dependency Walker时,打开文件后可以看到所使用的基本要求。只有在执行程序并运行其所有功能时,才能找到所有动态加载的DLL。

如果可能的话,有时最好询问开发人员需要哪些DLL。例如,当应用程序即将崩溃时,仅在绝对需要时才会加载某些DLL,例如加载faultrep.dll以进行自定义Windows错误报告。


不是真的关于延迟加载DLL,它们与常规DLL一样在exe的导入部分中。但我同意,要找到动态加载的DLL,您需要挂钩LoadLibrary()并执行exe中所需的代码路径。 - Len Holgate

1

0

你可以编写一个控制台应用程序来封装它,创建一个 PowerShell 脚本,或者像我通常做的那样,将以下内容添加到你的代码中进行快速检查:

    private static HashSet<string> ReferencedAssemblies = new HashSet<string>();

    ...
    OutputDependencies(Assembly.GetAssembly(typeof(Program)), 0);
    ...

    static void OutputDependencies(Assembly assembly, int indent)
    {
        if (assembly == null) return;

        Console.WriteLine(new String(' ', indent * 4) + assembly.FullName);
        if (!ReferencedAssemblies.Contains(assembly.FullName))
        {
            ReferencedAssemblies.Add(assembly.FullName);

            foreach (var childAssembly in assembly.GetReferencedAssemblies())
            {
                OutputDependencies(Assembly.Load(childAssembly.FullName), indent + 1);
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接