Dependencies 完全实战指南:一条命令导出完整依赖链,接入 CI 做回归排查
【免费下载链接】DependenciesA rewrite of the old legacy software "depends.exe" in C# for Windows devs to troubleshoot dll load dependencies issues.项目地址: https://gitcode.com/gh_mirrors/de/Dependencies
客户机器上报 0xC000007D,Event Viewer 里只有一句“The specified procedure could not be found”。这时你需要的是做依赖链分析与 DLL 排查的工具:Dependencies——depends.exe 的现代 C# 重写版,一条命令导出完整依赖链和导入/导出表。
工具定位:替代 depends.exe 的现代实现
Dependencies 用 C# 重写了随 Windows SDK 分发、早已停止维护的 depends.exe(Dependency Walker)。它模拟 NT Loader 的 DLL 查找顺序递归解析依赖链,原生支持 ApiSet 重定向和 x86/x64 混合环境。CLI 与 GUI 共享同一套解析引擎(核心 PE 解析在 ClrPhlib/src/unmanaged/UnmanagedPE.cpp):命令行版适合自动化,GUI 版适合交互式排查。
获取 Dependencies 与首次运行:一条命令解析依赖链
两种获取方式:
- 源码构建:克隆仓库(https://gitcode.com/gh_mirrors/de/Dependencies),打开 Dependencies.sln,手动选择
Release配置和x64平台——默认值可能不是这两个。 - 下载发布包:从 Releases 页面下载压缩包,解压即用。
最简命令格式:
Dependencies.exe [OPTIONS] <FILE>不带参数运行或加-help,会打印完整帮助(帮助文案由 Dependencies/Program.cs 中的DumpUsage生成,以最新源码为准)。
⚠️ 注意:受 /clr 编译限制,运行 Dependencies 需要已安装 Visual C++ Redistributable;二进制未签名,SmartScreen 弹出警告属于正常现象。
排查场景一:用 -chain 导出完整依赖链,定位缺失 DLL
痛点:报“找不到模块”,但你不知道依赖树里哪一层断了。
Dependencies.exe -chain MyApp.exe输出怎么读:每行形如├ 模块名 (搜索策略) : 解析到的路径。搜索策略标明该 DLL 是按 NT Loader 的哪条规则找到的,常见值有ROOT、ApiSetSchema、WellKnownDlls、System32Folder、Environment、NOT_FOUND,完整枚举见 DependenciesLib/FindPeModule.cs。标注NOT_FOUND的节点就是你要找的缺失 DLL,它上面的父节点告诉你谁在引用它。
树太深时用-depth限制递归深度(默认无限):
Dependencies.exe -chain -depth 2 MyApp.exe只想快速核对“一共解析到哪些模块”,用-modules输出按策略排序的扁平清单;问题涉及 WinSxS 组件库时,用-sxsentries列出文件的 SxS 依赖项,未解析的条目路径带???标记(解析逻辑在 DependenciesLib/SxsManifest.cs)。
💡 同一个 DLL 在不同环境可能命中的策略不同(开发机上
ApplicationDirectory命中,客户机上NOT_FOUND),对比两侧输出里的策略字段,往往比只看路径更能定位问题。
排查场景二:用 -imports / -exports 转储导入表与导出表
痛点:报的不是“找不到模块”而是“找不到过程”——DLL 加载了,但函数不在。
Dependencies.exe -imports MyApp.exe Dependencies.exe -exports kernel32.dll输出怎么读:-imports按导入源 DLL 分组,函数按名字或Ordinal_xxx(序数导入)输出,延迟加载项会单独标注(Delay Import);-exports列出每个导出的序数、名称和虚拟地址,转发导出会多一行ForwardedName——说明该函数实际由另一个 DLL 定义,顺着转发名去找真正的实现。
⚠️ 延迟导入的 DLL 直到首次调用函数时才加载,缺了它程序启动不会崩,而是运行到某个功能点才触发崩溃。看到
(Delay Import)标注的条目,优先核实对应 DLL 是否随包分发。
排查场景三:.NET 程序集与清单排查
痛点:.NET 程序报程序集解析失败,或者清单缺失导致权限、兼容性问题。
Dependencies.exe -assemblyrefs MyApp.exe Dependencies.exe -modulerefs MyApp.exe Dependencies.exe -manifest MyApp.exe输出怎么读:-assemblyrefs列出程序集引用,并尝试在本地(目标文件所在目录)解析出实际版本,解析不到就只打印名字;-modulerefs列出模块引用;-manifest转储文件内嵌的 SxS 清单(XML 格式),清单格式非法时直接输出解析异常。
仓库自带的回归脚本 test/manifest-regress/Test-ManifestRegress.ps1 就是用-manifest验证 asmv3 命名空间、资源索引 > 1 等边界用例的,写自己的验证脚本可以参考它的断言思路。
JSON 输出接入 CI 回归:三种典型玩法
大多数命令都支持-json开关,把结果序列化为缩进 JSON(序列化实现在 Dependencies/Program.cs 的JsonPrinter):
Dependencies.exe -json -chain MyApp.exe > deps.json Dependencies.exe -json -imports MyApp.exe三个 CI 玩法:
- 依赖变更检测:每次构建后导出 JSON 快照,与基线 diff,依赖集悄悄变了就能及时发现;
- 缺失 DLL 断言:脚本解析 JSON,只要存在
SearchStrategy: "NOT_FOUND"的节点就让流水线失败; - 报告归档:把
deps.json作为构建产物归档,事后排查有据可查。
PowerShell 场景直接ConvertFrom-Json消费输出即可,无需额外依赖。
📌 注意:
-modules目前不支持 JSON 输出,源码会直接提示“Json output is not currently supported”。自动化脚本请改用-chain或-imports。
系统级诊断:-knowndll / -apisets 速查
这些开关不依赖目标文件,用于排查系统级依赖问题:
| 命令 | 作用 |
|---|---|
-knowndll | 列出系统 KnownDlls 白名单(x86 与 x64),解释“为什么加载了 System32 里那个同名 DLL” |
-apisets | 转储系统 ApiSet 重定向表(api-ms-win-core-*.dll→ 宿主 DLL) |
-apisetsdll <FILE> | 从apisetschema.dll文件转储 ApiSet 表,仓库 test 目录下有apisetschema.v*.dll测试素材 |
-cache | 启用二进制缓存:读取时把 PE 复制到%LocalAppData%\Dependencies再打开,防止原文件被锁定 |
ApiSet 就像一张 DLL 的“转发路由表”:Windows 8.1 起大量api-ms-win-*.dll在磁盘上并不存在,加载器靠这张表找到真正的宿主 DLL。“找不到 api-ms-win-*.dll”的报错,根源通常是宿主 DLL 缺失,跑一次-apisets对照即可排查。
完整参数速查表
| 参数 | 需要 FILE | JSON 支持 | 一句话说明 |
|---|---|---|---|
-chain | 是 | 支持 | 转储完整依赖链(递归树) |
-modules | 是 | 不支持 | 转储已解析模块的扁平清单 |
-imports | 是 | 支持 | 转储导入表(函数级,含延迟导入) |
-exports | 是 | 支持 | 转储导出表(含转发导出) |
-assemblyrefs | 是 | 支持 | 转储 .NET 程序集引用 |
-modulerefs | 是 | 支持 | 转储模块引用 |
-manifest | 是 | 支持 | 转储内嵌 SxS 清单 |
-sxsentries | 是 | 支持 | 转储 SxS 依赖项 |
-apisetsdll | 是 | 支持 | 从 apisetschema 文件转储 ApiSet 表 |
-knowndll | 否 | 支持 | 列出系统 KnownDlls |
-apisets | 否 | 支持 | 转储系统 ApiSet 重定向表 |
-json/-cache/-depth N/-help | — | — | 全局开关 |
收尾
Dependencies 把退役的 depends.exe 的排查能力装进了脚本:-chain看清依赖全貌,-imports/-exports定位函数级问题,-json让整个排查过程可复现、可回归。对长期和 DLL 加载问题打交道的 Windows 开发者,它是当前最值得放进工具箱的开源方案。
【免费下载链接】DependenciesA rewrite of the old legacy software "depends.exe" in C# for Windows devs to troubleshoot dll load dependencies issues.项目地址: https://gitcode.com/gh_mirrors/de/Dependencies
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考