简介:DependenciesGui 的 Windows 10 依赖分析包面向 64 位系统用户与开发者,主要用于排查程序启动失败、缺少动态链接库或驱动组件等常见问题,也便于梳理应用程序的依赖链与部署条件。压缩包采用 7z 格式,共 35 个文件,约 1.78MB;其中 4 个可执行程序包含主程序与测试程序,12 个动态链接库承载界面和依赖解析等运行库,13 个调试符号文件用于保留调试信息,另有 4 个配置文件与 2 个 XML 文档,目录结构清晰,便于查看和复用。已有 690 人学习下载。Releasex64 目录中的图形界面程序可加载目标文件,展示依赖项的路径、版本以及更深层依赖关系,为缺失组件定位、打包检查和跨环境迁移提供参考;附带的符号与测试文件也有助于进一步观察分析过程,并辅助理解依赖加载机制。
1. 从一次双击无反应的 DependenciesGui 说起:depends 这套环境到底装的是什么
在一台刚装完的 Windows 10 22H2 上,双击 DependenciesGui.exe 什么也没发生——没有报错框,没有窗口,任务管理器里进程闪一下就消失。我是在排查「模拟项目X 的 exe 拷到另一台机器就起不来、事件查看器只留一个 0xc0000135」时撞上的:本来只想装个 depends 工具把依赖树摊开看清楚,结果分析工具自己先躺下了。
DependenciesGui 是 Dependency Walker 那一套的现代替代,Windows 上查 PE 导入表、延迟加载、SxS 清单、API 集转发,基本绕不开它。它没有安装程序,压缩包解开就能用;也正因为太“绿色”,很多人直接扔进 Program Files 或者桌面就双击,然后被运行库、位数、路径三件事轮流教训。下面按我自己装机的顺序走:对齐环境、落盘、配参数,最后给一份能打勾的验证清单。
2. 环境对齐:Windows 10 22H2 上跑 DependenciesGui 的三个前置条件
先把结论摆前面:这东西是原生 C++ 写的桌面程序,不需要 Python、不需要 .NET、不需要 Node,也不需要装什么服务端。好处是干净,坏处是它不会像那些带运行时的工具一样给你一句“缺少某某依赖”的友好提示——缺 MSVC 运行库时最典型的表现就是静默退出,连个错误码都不留。所以环境对齐这一步省不掉,三条:运行库、位数、落盘位置。
2.1 运行库:MSVC 2015-2022 是绕不过去的那道门
Windows 10 自带 .NET Framework,也自带一堆系统 DLL,但唯独不带 VC++ 运行库。DependenciesGui 用 MSVC 编译,启动时动态链接 VCRUNTIME140.dll、MSVCP140.dll 这一组,机器上没有就直接死在加载器阶段。
先查一遍本机装了什么,别凭感觉:
# 两个注册表分支分别对应 64 位与 32 位安装记录,WOW6432Node 那条是 x86 包的落脚点 Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*', 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' | Where-Object { $_.DisplayName -like '*Visual C++*Redistributable*' } | Select-Object DisplayName, DisplayVersion | Sort-Object DisplayName命令本身不复杂,关键是看懂输出。DisplayVersion里以 14 开头(14.2x、14.3x、14.4x)的都是 2015-2022 这一代,微软从 VS2015 起把运行库做成二进制兼容,一个 14.x 的包顶五代,不用去追 2015、2017、2019 各装一遍。如果输出里只有 x86 没有 x64,那 x64 版的 GUI 铁定起不来。
装的时候能用 winget 就用 winget,省得去翻下载页:
# --id 精确匹配包标识,避免装到同名的别家运行库 winget install --id Microsoft.VCRedist.2015+.x64 --accept-source-agreements --accept-package-agreements winget install --id Microsoft.VCRedist.2015+.x86 --accept-source-agreements --accept-package-agreements两个--accept参数是给无人值守场景用的,省掉交互确认;手动敲一次也无所谓。两个包都装的理由很实在:你分析的目标可能是 32 位插件,而插件跑在 64 位进程里的时候,你手上两套工具都得能开。Win10 1809 以前的版本、LTSC 精简版不一定带 winget,那就去下 vc_redist.x64.exe 和 vc_redist.x86.exe 手动装,效果一样。
注意:装完运行库不需要重启,但已经打开着的终端和资源管理器不会重新读环境,双击测试前先把旧窗口关掉。
2.2 位数选择:x64 和 x86 看的是被分析对象,不是你的系统
这一步翻车率比运行库还高。很多人的直觉是“我系统是 64 位,那就下 x64 包”,然后拿 x64 版去开一个 32 位的业务 DLL,出来一堆莫名其妙的红色条目,还以为是目标文件坏了。
正确的判断依据是你要分析的那个文件是多少位,不是你的操作系统多少位。
| 分析目标 | 该用哪个包 | 说明 |
|---|---|---|
C:\Windows\System32\下的 exe/dll | x64 | 系统目录本身就是 64 位主目录 |
C:\Windows\SysWOW64\下的 dll | x86 | 这个目录名反直觉,里面全是 32 位 |
| 自己编的 32 位插件、老版客户端 | x86 | 位数跟着目标走 |
| 一个 32 位进程加载的扩展模块 | x86 | 看宿主进程位数,不看模块文件后缀 |
| 两个都要查 | 两套都解压 | 放不同目录,别混在一起 |
跨位数打开不是绝对不能开,但遇到 CLR 程序集、SxS 清单、延迟加载这几类解析时,很容易给出半截结果——模块树看着正常,点进去导入表是空的。这种“看起来成功了其实没解析”的结果比报错更坑,因为你会拿它去下结论。我一般严格位数对齐,宁可多解压一个目录。
两个包共存的时候有个细节:不要把它们解压到同一个文件夹,也不要把两边的 exe 拖到一起。文件名相同的东西(同名的辅助 dll、配置文件)会互相覆盖,最后你分不清手上跑的是哪一版。
2.3 落盘位置与账号权限:为什么别放 Program Files
绿色程序最容易犯的错就是往 Program Files 里塞。这类程序运行时会往自身目录写配置、写符号缓存,而 Program Files 默认对普通用户只读,UAC 的虚拟化会把写入重定向到%LOCALAPPDATA%\VirtualStore下面。表现是:这次配好的模块搜索路径,换个账号登录或者过两天再开,配置全没了——因为写进去的和读出来的根本不是同一个文件。
我固定的放法是:
C:\Tools\Dependencies\x64\ <- 64 位包解压到这里 C:\Tools\Dependencies\x86\ <- 32 位包解压到这里 C:\Tools\Dependencies\symbols\ <- 符号缓存,单独一层 C:\Tools\Dependencies\out\ <- 命令行导出的文本报告路径上还有两个规避项。一是不要带中文,二是不带空格。这不是玄学,符号路径和搜索路径在界面里是一串用分号拼起来的东西,遇到空格和中文时个别版本拼串会失败,症状就是“明明目录加进去了,还是标红”。我不确定新版有没有彻底修掉,但换成一个纯英文短路径的成本是零,没必要去赌。
第三个规避项是别放 OneDrive 或者任何同步盘目录。同步客户端会周期性锁文件做上传,正好撞上你打开大文件解析的时候,轻则读一半失败,重则 exe 被占用无法更新。这类问题排查起来极其费时间,因为它是间歇性的。
3. 下载与落盘:把 Release 压缩包变成一个能双击的依赖分析工具
拿到 Release 压缩包之后,真正需要动手的只有三件事:解压到正确位置、解除网络文件锁定、把命令行版暴露到 PATH。每一步都不长,但跳过的代价都不小。
3.1 解压:Expand-Archive 之后该看到什么
不要用第三方解压软件一路“下一步”,也不要把 exe 单独拖出来。用 PowerShell 解压,路径可控,重复执行也安全:
# 源压缩包按你实际下载的位置改 $zip = "$env:USERPROFILE\Downloads\Dependencies_x64_Release.zip" $dst = 'C:\Tools\Dependencies\x64' New-Item -ItemType Directory -Force -Path $dst | Out-Null # -LiteralPath 防止路径里的方括号被当成通配符,-Force 允许覆盖旧版本 Expand-Archive -LiteralPath $zip -DestinationPath $dst -Force # 落盘之后立刻确认内容,别急着双击 Get-ChildItem $dst | Select-Object Name, Length | Format-Table -AutoSize-LiteralPath这个参数值得说一句:默认的-Path会把[]当通配符处理,如果你的下载目录或者用户名里恰好有方括号,解压会静默失败或者解到奇怪的地方。加上这个参数就没这回事。
解压完应该看到一个 GUI 主体程序(DependenciesGui.exe)、一个命令行版本(不同发布版本叫 Dependencies.exe 或者 DependenciesCLI.exe,以你看到的为准),以及若干同目录的辅助文件。判断标准很简单:GUI 和 CLI 在同一层,辅助文件在它们旁边。如果你解压完只看到一个孤零零的 exe,那多半是解压工具把子目录结构压平了,或者你下的是某个精简转载包,重新下一次原包。
注意:只把 DependenciesGui.exe 复制到桌面,是最常见的错误起点。缺了同目录的配套文件之后,症状和“没装运行库”几乎一模一样,都会让你在错误的方向上排查半小时。
3.2 解除锁定与杀软白名单:Zone.Identifier 是个隐形黑匣子
从浏览器下载的压缩包,Windows 会给它打一个备用数据流标记,解压出来的文件继承这个标记。带标记的 exe 双击时可能被 SmartScreen 拦下来,也可能被安全软件按“来源不明的可执行文件”处理。界面上有时给提示,有时什么都不给,直接静默拦掉——这就是前面说的“双击没反应”的另一个成因。
一条命令递归清掉:
# 递归解除整个工具目录的锁定,等价于逐个文件右键属性里点“解除锁定” Get-ChildItem 'C:\Tools\Dependencies' -Recurse -File | Unblock-FileUnblock-File干的事情就是删掉那个 Zone.Identifier 流,不改文件内容。以后每次升级换版本、换目录,重新跑一遍就行,成本很低。
企业环境里还有一层:EDR 或者杀软。DependenciesGui 的典型行为是枚举大量进程模块、读取别的 exe 的导入表、往缓存目录写 PDB 文件,这套动作在启发式规则里长得跟信息收集类程序很像。表现是解压完 exe 直接消失,或者第一次运行到一半被终止。处理方式是给整个C:\Tools\Dependencies目录加白名单,不是关掉防护。加白名单之后仍然报毒,那就换个目录名再试一次——有些规则是按路径特征匹配的。
3.3 进 PATH 与做快捷方式:让命令行版也能随手调
GUI 可以靠快捷方式点,命令行版要能随手敲,就得进 PATH。改用户级 PATH 不需要管理员权限,也不会污染系统级配置:
# 读取当前用户级 PATH,追加工具目录后写回 $old = [Environment]::GetEnvironmentVariable('Path', 'User') $new = "$old;C:\Tools\Dependencies\x64" [Environment]::SetEnvironmentVariable('Path', $new, 'User') # 验证:新开一个终端,看拆分后有没有目标目录 $env:Path -split ';' | Where-Object { $_ -like '*Dependencies*' }这里刻意没用setx。setx有两个老问题:超过 1024 个字符会截断,而 PATH 超长在装了一堆 SDK 的机器上是常态;另外它写入的是展开后的值,会把别人的%JAVA_HOME%之类变量直接固化成字面路径。用 .NET 的SetEnvironmentVariable走注册表原始值,这两个坑都避开。
改完 PATH 必须新开终端才生效,已经开着的窗口读的是启动时的快照。验证那行如果输出为空,先别怀疑命令写错了,开个新窗口再试。
提示:如果团队里多人要用,可以把“解压 + 解除锁定 + 加 PATH + 跑一次自检”写成一个 ps1 脚本放在共享目录,比口头交代可靠得多。
4. 参数配置:模块搜索路径、符号缓存和命令行导出怎么设
工具能开起来只是第一步。真正决定这份依赖树能不能用的,是解析阶段的两个路径配置——模块搜索路径决定“找不找得到 DLL”,符号路径决定“看不看得到函数级信息”。这两件事配错,输出就是一堆看着吓人的红色条目。
4.1 模块搜索路径:三个必加目录和它们的优先级
原理不复杂:PE 文件的导入表里,大部分条目只记了模块名(比如MSVCP140.dll),没记完整路径。工具要还原出“这个 DLL 到底来自哪里”,就得按一套搜索顺序去磁盘上找。找不到就标红,标注为缺失。
搜索顺序大致是:目标文件所在目录 → 你配置的搜索目录 → 系统目录 → 环境变量 PATH 里的目录。界面里改的地方在 Options 菜单下,不同版本措辞略有差别,找 “Module Search Path” 或 “Configure Module Search Path” 这类字眼就对了。
不管目标是什么,我固定会加这三个:
- 目标文件所在目录。这是最重要的一条。很多人把待查的 exe 从构建机拷到本机,配套 DLL 留在原目录没拷过来,于是工具按本机路径找,当然找不到。
- 目标程序自己的插件/Lib 子目录。主程序目录下常常有
plugins、lib、bin这类子目录,导入表里写的是相对名,搜索路径不包含它就一定标红。 - 第三方库的落地目录。自己编译的东西尤其需要,编译期的 lib 目录和运行期的 dll 目录经常不是同一个。
改完搜索路径,界面上一般要重新加载一次目标文件才生效——不是刷新一下就行,得关掉重新打开。这个细节坑过不少人:路径加对了,看着还是红的,以为配置没生效,其实是缓存没刷新。
命令行版如果有对应的目录参数,优先级和界面里是一致的;参数名各版本有出入,先看帮助再抄,别照搬网上的旧命令。
4.2 符号路径:什么时候需要 PDB,_NT_SYMBOL_PATH 怎么写
先说结论:只想知道缺哪个 DLL,不需要配符号。导入表、导出表、延迟加载、SxS 清单这些信息全在 PE 文件本身里,跟 PDB 无关。
需要配符号的场景有三个:要看函数级的导出清单、要区分某些内部调用、要排查 CLR 程序集里的具体方法。这三种都属于“我已经知道缺什么了,想再往下挖一层”。
配置方式有两种,界面里 Options 下有一处符号路径的设置,环境变量_NT_SYMBOL_PATH也会被读。我习惯用环境变量,因为命令行版和 GUI 版会共用同一份配置:
# 缓存目录先建好,符号文件动辄几百 MB,放 SSD $cache = 'C:\Tools\Dependencies\symbols' New-Item -ItemType Directory -Force -Path $cache | Out-Null # 三段式:srv*缓存目录*符号服务器地址 [Environment]::SetEnvironmentVariable( '_NT_SYMBOL_PATH', "srv*$cache*https://msdl.microsoft.com/download/symbols", 'User' )三段式的含义:srv表示启用符号服务器协议,中间是本地缓存目录,最后是远端地址。第一次解析会去远端拉,拉下来的存进缓存目录,第二次就纯本地读。缓存目录放在机械盘上会让首次解析慢到你以为卡死了,能放 SSD 就放 SSD。
内网环境访问不到公共符号服务器时,把最后一段去掉,只留srv*C:\Tools\Dependencies\symbols,然后让编译流水线把 PDB 提前拷进这个目录。工具找不到就跳过符号,不会因此崩溃,只是导出清单里少了函数名。
注意:如果系统 PATH 里存在别的软件附带的旧版 dbghelp.dll 或 symsrv.dll,可能被优先加载,导致符号解析一路报错。判断方法见第 5 章。
4.3 命令行版:批量导出依赖清单的写法
单个文件用 GUI 看很舒服,但要对比几十个产物的依赖变化,就得靠命令行。第一步永远是看帮助,别抄旧命令:
# 先看这个版本支持哪些参数,不同发布版本参数名有调整 & 'C:\Tools\Dependencies\x64\Dependencies.exe' -h看清楚之后再写导出。下面这段以模块列表为例,别的子命令换成对应参数即可:
$cli = 'C:\Tools\Dependencies\x64\Dependencies.exe' $out = 'C:\Tools\Dependencies\out\notepad-modules.txt' New-Item -ItemType Directory -Force -Path (Split-Path $out) | Out-Null # 2>&1 把标准错误一起收进来,避免解析失败的提示被丢掉 & $cli -modules 'C:\Windows\System32\notepad.exe' 2>&1 | Out-File -FilePath $out -Encoding utf8 "exit=$LASTEXITCODE size=$((Get-Item $out).Length)"三个地方值得说明。2>&1是为了把错误流并进输出,否则解析失败时文件是空的,你还以为工具没跑。Out-File -Encoding utf8是为了让带中文的路径名不乱码。$LASTEXITCODE是判断成功与否的硬指标——输出非空不代表成功,有时代码出错也会打印半截内容。
批量跑整个构建目录:
Get-ChildItem 'D:\build\out' -Filter *.exe -Recurse | ForEach-Object { # 用完整路径的哈希做文件名,避免不同子目录里同名 exe 互相覆盖 $hash = [System.BitConverter]::ToString( [System.Security.Cryptography.MD5]::Create().ComputeHash( [Text.Encoding]::UTF8.GetBytes($_.FullName) ) ).Replace('-', '').Substring(0, 8) $target = "C:\Tools\Dependencies\out\$($_.BaseName)-$hash.txt" & 'C:\Tools\Dependencies\x64\Dependencies.exe' -modules $_.FullName 2>&1 | Out-File -FilePath $target -Encoding utf8 "{0} -> exit {1}" -f $_.FullName, $LASTEXITCODE }BaseName单独用一定会撞名,bin\Debug和bin\Release下各有一个同名 exe 是常态。取完整路径的哈希前 8 位当后缀,既保证唯一又不至于文件名长到撞上 260 字符限制。这套写法我拿去对比过一次发版前后的依赖差异,直接定位到一个第三方库被静默升级了主版本号——差分这活儿靠人眼看 GUI 是做不完的。
5. 常见问题排查:DependenciesGui 打不开、依赖树一片红的五个现场
把问题按阶段分两类会好查很多:启动阶段的问题(进程根本起不来)和加载阶段的问题(能开但解析结果不对)。这两类的成因几乎没有交集,混在一起想就会乱。
5.1 启动阶段:闪退、0xc000007b、被杀软拦
现场一:双击没反应,进程闪一下就没了
现象:任务管理器里 DependenciesGui.exe 出现又消失,没有窗口,没有错误框,事件查看器里可能有一条 Application Error。
原因:九成是缺 MSVC 运行库,或者 x64 版配了 x86 的运行库。加载器在解析导入表阶段就失败了,失败得太早,程序自己的错误处理还没机会跑起来,所以什么都不显示。
解决:按 2.1 节把两个位数的运行库都装上;然后去看事件日志确认,比猜快得多:
# 只看最近 5 条应用程序错误,重点看 Faulting module name Get-WinEvent -FilterHashtable @{LogName='Application'; Id=1000} -MaxEvents 5 | Select-Object TimeCreated, Message | Format-ListFaulting module name如果指向VCRUNTIME140.dll或MSVCP140.dll,就是运行库问题;如果指向ntdll.dll且错误码是0xc000007b,看下一个现场。
现场二:弹窗报“应用程序无法正常启动 (0xc000007b)”
现象:一启动就弹这个框,点确定退出。
原因:位数混装。最常见的是把 x64 的 exe 和 x86 的辅助 dll 放进了同一个目录,或者反过来;其次是系统 PATH 里存在别的软件带的同位数错误 dll,被优先加载。
解决:整包重新解压,不要手工拼接 dll——手工拼是这类问题的头号制造者。怀疑 PATH 冲突时,临时清空 PATH 再启动一次做对照:
# 只保留系统必需目录,启动后再恢复,用于判断是否是 PATH 里的同名 dll 顶掉了 $bak = $env:Path $env:Path = "$env:SystemRoot\System32;$env:SystemRoot" & 'C:\Tools\Dependencies\x64\DependenciesGui.exe' $env:Path = $bak临时改的$env:Path只影响当前这个 PowerShell 会话,关掉窗口就恢复,不会污染系统配置。这一步只是定位手段,不是修复手段。
现场三:解压后 exe 直接被删,或者提示“Windows 已保护你的电脑”
现象:解压完成,文件列表里少了 exe;或者双击弹 SmartScreen 的拦截框,只有“不运行”可选。
原因:下载标记(Zone.Identifier)没清,或者安全软件按启发式规则判定可疑。
解决:跑 3.2 节那条Unblock-File;SmartScreen 拦截框里如果有“更多信息”,点开能看“仍要运行”;安全软件侧加目录白名单而不是整体关闭。加完白名单仍被删,换个目录名重新解压——有些规则按路径匹配。
5.2 加载阶段:满屏标红、符号卡住、中文路径崩溃
现场四:打开目标 exe,连 KERNEL32.dll 都是红的
现象:模块树里从系统 DLL 开始就一片红,看起来什么都缺。
原因:两个可能。一是模块搜索路径没包含目标所在目录,工具在本机按名字找,找到的是本机的同名文件,版本对不上就判缺失;二是工具位数和目标位数不一致,解析出来的导入表本身就是残缺的。
解决:先确认位数对齐,再把目标目录加进搜索路径并重新打开文件(不是刷新,是关掉重开)。快速验证的办法是把目标及其依赖一起复制到一个干净的空目录再打开——如果红色消失了,说明就是搜索路径的问题,不是文件本身坏了。
现场五:符号一直加载不出来,或者提示无法连接符号服务器
现象:状态栏卡在加载符号,几分钟不动;或者直接报错说找不到了符号。
原因:网络到不了公共符号服务器;或者本机 PATH 里存在旧版 dbghelp.dll/symsrv.dll 被优先加载,版本不匹配导致解析失败。
解决:先把_NT_SYMBOL_PATH简化成纯本地缓存(4.2 节那段的中间态),确认工具本身没问题;再确认工具目录里的 dbghelp 没被别家顶掉。判断方法很直接:
# 列出当前会话下所有能命中的 dbghelp.dll,第一条就是会被加载的那个 where.exe dbghelp.dll如果第一条不是工具目录下的,也不是System32下的,那就是冲突源。把那个目录从 PATH 里挪走,或者干脆用完整路径调用 GUI。
现场六:打开中文路径或者超长路径的文件,程序直接退出
现象:从列表里点某个文件,或者把路径粘进地址栏,窗口消失。
原因:PE 解析本身没问题,但界面里拼路径的地方对非 ASCII 字符敏感,加上路径过长时会触发另一类问题。
解决:把文件复制到C:\tmp\a.exe再看一次。这是最快的判定手段——复制到短英文路径就正常,说明是路径问题,跟文件本身无关;复制过去还是崩,才需要往文件损坏方向查。
6. 装完怎么验证:拿 notepad.exe 打底的三步自检
装完不验证,等于没装。这套工具最麻烦的地方在于:它出错的时候往往不报警,只是给你一份错的依赖树,然后你拿着错结论去改代码或者改部署脚本。所以我给自己定了一套固定动作,换机器、换版本、换账号都跑一遍。
6.1 三步自检清单
| 验证项 | 怎么做 | 期望结果 | 不通过怎么办 |
|---|---|---|---|
| GUI 能启动 | 双击 DependenciesGui.exe | 窗口正常出现,标题栏能看到版本信息 | 回第 5 章现场一、现场二 |
| 解析系统文件正常 | 打开C:\Windows\System32\notepad.exe | KERNEL32.dll、USER32.dll、GDI32.dll 及api-ms-win-*系列全部正常显示,无大面积标红 | 回现场四,检查位数与搜索路径 |
| 命令行能出结果 | 跑一次 CLI 并检查退出码 | 输出文件非空,$LASTEXITCODE为 0 | 回现场五,检查符号与运行库 |
为什么拿 notepad.exe 打底?因为这个文件的依赖是已知的、稳定的、每台 Windows 上都在的。它要是一片红,问题一定出在工具侧,跟你正在排查的业务 exe 无关。反过来,notepad 正常而业务 exe 标红,那红色就是真实信息,可以往下查了。这一条能省掉大量“到底是工具坏了还是我的文件坏了”的来回怀疑。
6.2 把自检写成一条命令
手动点三遍不难,难的是每次都记得点。所以我把它固化成一个判断,跑完直接看 PASS/FAIL:
$cli = 'C:\Tools\Dependencies\x64\Dependencies.exe' $out = 'C:\Tools\Dependencies\out\selfcheck.txt' New-Item -ItemType Directory -Force -Path (Split-Path $out) | Out-Null & $cli -modules 'C:\Windows\System32\notepad.exe' 2>&1 | Out-File $out -Encoding utf8 # 双条件:退出码为 0,且输出文件确实有内容(空文件不算通过) if ($LASTEXITCODE -eq 0 -and (Get-Item $out).Length -gt 0) { "PASS size=$((Get-Item $out).Length)" } else { "FAIL exit=$LASTEXITCODE size=$((Get-Item $out).Length)" }两个条件缺一不可。只判退出码,会在工具把错误信息当正常输出打到 stdout 的时候误报通过;只判文件大小,会在进程中途崩掉但已经写了半截日志的时候误报通过。加上2>&1把错误流并进来之后,空文件基本就等价于“什么都没解析出来”。
如果你想再稳一点,可以在自检之后顺手把 x86 版也跑一次,目标换成C:\Windows\SysWOW64\下的任意一个 dll,确认两个位数都能用。整个自检加上解压和配置,熟练之后五分钟能走完,比出问题之后再回头查快得多。
从那以后我每次在新机器上装这套东西,都会先跑一遍 notepad 那一关,确认工具本身是干净的,再去碰真正要查的那个 exe。血泪经验就一句话:别在工具没验证的情况下信它的结论。希望帮到你。
本文还有配套的精品资源,点击获取