如何获取给定 DLL 或 EXE 文件的所有 DLL 依赖项列表?
换句话说,我想以编程方式执行与“Dependency Walker”工具相同的操作。
有没有 Windows(最好是.NET)API 可以实现这一点?
如何获取给定 DLL 或 EXE 文件的所有 DLL 依赖项列表?
换句话说,我想以编程方式执行与“Dependency Walker”工具相同的操作。
有没有 Windows(最好是.NET)API 可以实现这一点?
注意:根据下面帖子的评论,我认为这个方法也可能会漏掉未管理的依赖项,因为它依赖于反射。
这是一段由Jon Skeet在bytes.com上编写的小型C#程序,用于.NET依赖关系检查器。
using System;
using System.Reflection;
using System.Collections;
public class DependencyReporter
{
static void Main(string[] args)
{
//change this line if you only need to run the code one:
string dllToCheck = @"";
try
{
if (args.Length == 0)
{
if (!String.IsNullOrEmpty(dllToCheck))
{
args = new string[] { dllToCheck };
}
else
{
Console.WriteLine
("Usage: DependencyReporter <assembly1> [assembly2 ...]");
}
}
Hashtable alreadyLoaded = new Hashtable();
foreach (string name in args)
{
Assembly assm = Assembly.LoadFrom(name);
DumpAssembly(assm, alreadyLoaded, 0);
}
}
catch (Exception e)
{
DumpError(e);
}
Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();
}
static void DumpAssembly(Assembly assm, Hashtable alreadyLoaded, int indent)
{
Console.Write(new String(' ', indent));
AssemblyName fqn = assm.GetName();
if (alreadyLoaded.Contains(fqn.FullName))
{
Console.WriteLine("[{0}:{1}]", fqn.Name, fqn.Version);
return;
}
alreadyLoaded[fqn.FullName] = fqn.FullName;
Console.WriteLine(fqn.Name + ":" + fqn.Version);
foreach (AssemblyName name in assm.GetReferencedAssemblies())
{
try
{
Assembly referenced = Assembly.Load(name);
DumpAssembly(referenced, alreadyLoaded, indent + 2);
}
catch (Exception e)
{
DumpError(e);
}
}
}
static void DumpError(Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error: {0}", e.Message);
Console.WriteLine();
Console.ResetColor();
}
}
虽然这个问题已经有了一个被接受的答案,但是其他答案中引用的文档,如果没有损坏,就是旧的。与其阅读所有内容,只发现它不涵盖Win32和x64之间的差异或其他差异,我的方法是这样的:
C:\UnxUtils\usr\local\wbin>strings.exe E:\the-directory-I-wanted-the-info-from\*.dll > E:\TEMP\dll_strings.txt
为了获取本地模块依赖项,我认为从PE文件的导入表中获取应该是可以的,以下是两个详细解释的链接:
http://msdn.microsoft.com/en-us/magazine/bb985992.aspx
http://msdn.microsoft.com/en-us/magazine/cc301808.aspx
要获取.NET依赖项,我们可以使用.NET的API,比如Assembly.Load。
要获取一个.NET模块的所有依赖项,我们可以结合两种方法 - .NET程序集只是带有元数据的PE文件。
不确定它对于运行中的.Net exe会显示什么(我从未尝试过)。但是,它确实显示了从哪里加载了DLL的完整路径。通常,这是我在解决DLL问题时所需的信息。据说.Net已经删除了使用这些函数的必要性(查找DLL Hell以获取更多信息)。
如果您不想在程序中加载程序集,可以使用 DnSpy(https://www.nuget.org/packages/dnSpyLibs):
var assemblyDef = dnlib.DotNet.AssemblyDef.Load("yourDllName.dll");
var dependencies = assemblyDef.ManifestModule.GetAssemblyRefs();