Process Monitor(ProcMon)实战指南 —— 10 分钟定位「配置未生效」「ACCESS DENIED」问题
· Go Komura · Process Monitor, Sysinternals, 故障排查, 调试, 故障排除, Windows 开发, 运维, 技术咨询
「明明修改了配置文件,应用的行为却没有变化」「开发机上能正常运行,唯独客户端一启动就崩溃」「直到昨天都还能正常运行,程序完全没有改动过」——故障排查的委托,大多是以这种形式出现的。而这类症状,即便反复阅读源代码,往往也无法找到原因。因为应用实际读取了哪个文件、查看了哪个注册表、又在哪里失败,是由运行环境而非代码决定的。
能够记录下这些「实际发生了什么」的,正是 Microsoft 免费提供的 Sysinternals 工具之一 Process Monitor(ProcMon)。它会将文件系统、注册表、进程/线程的活动全部实时记录下来,可以说是Windows 的行为日志记录仪,在本公司的故障排查工作中,也是与 WinDbg 并列的高频工具。1
然而它虽然强大,如果什么都不做直接启动,每秒就会涌入成千上万条事件,初次接触的人往往会以「太多了根本看不过来」而告终。本文将从故障排查一线的视角,整理出在实际工作中运用 ProcMon 的最短路径——Filter 的设置方法、Result 列的解读方式、按症状分类的常见排查模式、在生产环境中使用的注意事项,以及与其他排查工具的搭配使用方式。
1. 先说结论
- ProcMon 能够回答的问题是「这个进程在何时、对哪个路径、做了什么、结果如何」。配置文件是从哪里被读取的、DLL 是按什么顺序被搜索的、哪个操作出现了 ACCESS DENIED,这些都能在几分钟内查清。
- 使用的标准套路是「先用 Process Name 对目标进程设置 Include,再用 Result 缩小到异常类」。它不是一个需要从头到尾逐行阅读原始事件的工具。
- Result 列中有大量看似异常实则正常的结果。BUFFER OVERFLOW 是正常的 API 往返,NAME NOT FOUND 大多只是探索顺序中的中间过程而已(第 4 章)。
- Filter 只是显示层面的筛选,后台依然记录着全部事件。保存日志交给他人时,应保存全部事件;反过来,在长时间抓取时,则应通过 Drop Filtered Events 来保护内存(第 5 章)。
- ProcMon 并非万能。「现在是哪个进程占用了这个文件」属于 Process Explorer 的范畴,崩溃瞬间的状态属于崩溃转储的范畴,CPU 消耗在何处则属于 PerfView 的范畴(第 7 章)。
下面先给出一张根据症状选择工具的速查表。
| 症状 / 想了解的问题 | 首先使用的工具 |
|---|---|
| 配置未生效 / 想知道读取了哪个文件、注册表 | ProcMon |
| 仅在特定环境下无法启动、找不到 DLL | ProcMon |
| 定位 ACCESS DENIED 等权限相关的失败 | ProcMon |
| 文件删不掉,想知道是被谁占用的 | Process Explorer(句柄搜索) |
| 应用崩溃,想查明异常/崩溃的原因 | 崩溃转储 + WinDbg |
| 运行缓慢,想知道 CPU、内存消耗在何处 | PerfView / dotnet-trace |
| 长期运行中句柄、内存持续增长 | Process Explorer + 句柄泄漏排查 |
| 想查看通信的内容(数据包) | Wireshark / pktmon |
2. ProcMon 是什么 —— 一分钟即可完成安装
Process Monitor 是 Sysinternals 工具集中的一员,是能够实时显示文件系统、注册表、进程/线程活动的监控工具。它是整合并强化了曾经的 Filemon 与 Regmon 这两款工具而成的后继产品,具备逐事件的详细信息、非破坏性的 Filter、线程堆栈记录、启动时日志记录等功能。1
安装非常简单。它没有安装程序,只需从下载页面获取 ZIP 包并解压,运行 Procmon.exe 即可。如果情况紧急,也可以借助 Sysinternals Live 这项服务,直接从 https://live.sysinternals.com/procmon.exe 运行。2 首次启动时会要求同意使用许可协议,并且由于需要加载内核驱动程序,必须具备管理员权限(UAC 提升)。关于为何需要管理员权限的一般性说明,可参见笔者此前撰写的「何时需要 Windows 的管理员特权」一文,像这类查看整个操作系统事件的工具,正是典型的「需要提升权限」一方。
启动的瞬间抓取就会开始,事件会开始在画面上滚动显示。只需记住三个主要操作即可。
| 操作 | 快捷键 | 含义 |
|---|---|---|
| 开始/停止抓取 | Ctrl+E | 开启/关闭记录。基本原则是在复现操作前一刻开始,操作后立即停止 |
| 清除显示 | Ctrl+X | 重置画面显示。在复现操作前按下可以减少噪音 |
| Filter 对话框 | Ctrl+L | 添加/编辑筛选条件(第 3 章) |
一行事件由「Time(时间)・Process Name(进程)・PID・Operation(操作)・Path(目标路径)・Result(结果)・Detail(详情)」构成。Operation 大致对应 Win32 API 的粒度,例如 CreateFile(打开/创建文件)、ReadFile/WriteFile、RegOpenKey/RegQueryValue 等。也就是说,ProcMon 的日志是「应用与操作系统之间的对话记录」,应用「以为」自己在读取配置文件,而「实际」读取的是哪里,这两者之间的差异会原原本本地呈现出来。
3. Filter —— ProcMon 是先筛选、后阅读的工具
如果什么都不做直接抓取,即便是处于空闲状态的 Windows,每秒也会产生数千条事件。可以说 ProcMon 的实用性完全取决于 Filter 的用法,标准做法分为以下两个阶段。
第一阶段:按进程筛选。 用 Ctrl+L 打开 Filter 对话框,添加 Process Name / is / myapp.exe / Include。也可以将工具栏上的瞄准图标拖到目标应用的窗口上,只对该进程设置 Filter。
第二阶段:按结果或操作筛选。 如果想「找出失败的操作」,可以设置 Result / is not / SUCCESS / Include(只显示异常类)。如果想「只看写入操作」,可以设置 Category / is / Write / Include。如果想知道「是谁在触碰这个配置文件」,则不按进程筛选,而是设置 Path / contains / app.config / Include,诸如此类。
此外,在实际工作中还经常用到通过右键点击事件行进行交互式筛选的方法。一旦找到一行接近目标的事件,只需右键点击选择「Include ‘此路径’」或「Exclude ‘此进程’」,无需打开对话框就能不断叠加 Filter 条件。将噪音源(杀毒软件、索引程序等)通过 Exclude 逐一排除,只留下目标操作前后的内容,是基本的操作方式。用于辅助肉眼观察的还有高亮(Ctrl+H)功能,可以用与 Filter 相同的条件表达式给行标色,因此当「想看整体流程,但只想让异常类突出显示」时,应该使用高亮而不是 Filter。
有三个如果不了解就容易踩坑的特性。
- Filter 是显示层面的筛选,而不是记录层面的筛选。 在后台(默认情况下)会记录全部事件,只要取消 Filter,随时都能回到全部事件的视图。这正是它被称为非破坏性 Filter 的原因,其设计使得「筛选过度导致漏掉证据」的情况很难发生。1
- Filter 设置会延续到下次启动。 上次排查时的 Filter 残留下来,导致「什么都不显示」而困惑不已,是几乎每个人都经历过的一关。如果觉得显示不正常,请首先怀疑 Filter 菜单中的 Reset Filter(Ctrl+R)。
- 默认已经设置了若干 Exclude。 ProcMon 自身以及分页 I/O 等一开始就被排除在外。如果排查需求是「不遗漏地覆盖整个系统」,请注意这些默认 Filter 的存在。
4. Result 列的解读方法 —— 看似异常实则正常的情况
用 Filter 缩小到异常类之后,这次又会因为出现大量「看起来像异常的结果」而感到吃惊。这里重要的是,Result 列中的大多数异常值其实都是正常行为的一部分。下面汇总主要 Result 值的解读方式。
| Result | 含义 | 成为问题的可能性 |
|---|---|---|
| SUCCESS | 成功 | ——(不过有时「不该成功的地方却成功了」本身就是原因) |
| NAME NOT FOUND | 该路径下不存在此名称 | 低~中。多数是探索顺序中的过程。若最终未出现 SUCCESS 则是真凶 |
| PATH NOT FOUND | 中途的文件夹本身不存在 | 中。常见于拼写错误、文件夹未创建、环境差异 |
| ACCESS DENIED | 访问被拒绝 | 高。权限、ACL、杀毒软件、写入受保护区域 |
| SHARING VIOLATION | 共享冲突(其他进程以独占方式打开) | 高。文件锁定冲突,需定位对方进程 |
| BUFFER OVERFLOW | 缓冲区太小,因此返回了所需大小 | 无。正常的 API 往返(参见 FAQ) |
| REPARSE | 经过了重解析点(符号链接等) | 几乎没有。可作为路径重定向的痕迹来解读 |
| NO MORE FILES / NO SUCH FILE | 枚举结束等 | 几乎没有 |
其中,真正在排查中扮演主角的是 NAME NOT FOUND、ACCESS DENIED、SHARING VIOLATION 这三个。它们各自都有常见的排查模式,下一章将从症状的角度来逐一说明。
反过来容易被忽视的,是「SUCCESS 才是原因」的模式。举例来说,「修改过的配置文件没有生效」这个问题的答案,不止一次是成功读取(SUCCESS)了位于别处的旧配置文件。如果只盯着异常类看,就会漏掉这种被正常读取的「错误的正确答案」,因此按路径筛选、将该文件类型的所有访问(包括成功的)全部纳入视野,才是稳妥的做法。
5. 按症状分类的常见排查模式
5.1 「修改了配置却没有生效」—— 定位配置究竟是从哪里读取的
用 Path / contains / 配置文件名 设置 Include 后启动应用,就能看到应用从哪个文件夹、按什么顺序搜索了该名称的文件的完整列表。常见的真相通常是以下几种之一。
- 读取的并非与 exe 同一文件夹下的文件,而是
%APPDATA%或ProgramData下的副本(设计上是首次启动时进行复制) - 32 位进程对注册表、系统文件夹的访问受到了 WOW64 重定向的影响,导致「以为」查看的位置与实际位置产生了偏差
- 对安装目录
Program Files下的写入被虚拟化(VirtualStore)接管,读写操作实际发生在了别的位置
无论哪一种情况,只要使用 ProcMon,由于 Path 会显示完整路径,都能一目了然。关于配置文件应该如何设计存放位置这一反面话题,笔者曾在「不仅仅是 appsettings.json —— 配置管理实务」中写过。
5.2 「仅在这个环境下无法启动」—— 追踪 DLL 的搜索过程
如果应用在启动后立即崩溃、或出现「找不到 DLL」之类的错误,可以在按进程设置 Include 的基础上追加 Path / ends with / .dll,观察 NAME NOT FOUND 的连锁反应。由于 Windows 的 DLL 搜索是按固定顺序遍历文件夹的,ProcMon 的日志会原原本本地呈现出「按搜索顺序依次出现 NAME NOT FOUND,并在某处出现 SUCCESS(或者始终找不到)」这样的形态。始终没有出现 SUCCESS 的 DLL 就是元凶。反过来,「虽然出现了 SUCCESS,但抓取到的却是位于意料之外位置的旧版 DLL」这种模式,也能在这里被发现。关于搜索顺序的原理,请一并参阅「Windows DLL 名称解析机制」。
COM/ActiveX 相关的「类未注册」问题也是同样的类型,可以观察到针对 RegOpenKey 的 CLSID 下方的 NAME NOT FOUND。因 32 位/64 位混淆而查看了另一视图的注册表所导致的事故,正如笔者在「Office 2024/Microsoft 365 中 ActiveX 无法运行的原因与排查步骤」中所写的那样,使用 ProcMon 是最快的路径。
5.3 「出现 ACCESS DENIED」—— 怀疑是以谁的权限在运行
发现 ACCESS DENIED 后,双击该事件查看 Process 标签页,就能看到该进程当时是以哪个用户身份运行的,从而发现诸如「服务并非以 SYSTEM、而是以受限的服务账户运行」「仅在通过任务计划程序启动时使用了不同的用户」这类差异。如果目标是文件,只需与该路径的 ACL 进行比对即可确定原因。此外,在杀毒软件介入的情况下,经常能看到在前后紧邻的时间点,有另一个进程(杀毒软件的引擎)也触碰了同一路径,这也是按时间序列记录的 ProcMon 独有的证据形式。
5.4 「文件处理偶尔会失败」—— 寻找 SHARING VIOLATION 的对手
共享冲突是一种时间序列至关重要的排查。按路径设置 Include、不对进程设置 Filter 进行抓取,就能在失败瞬间前后的行中看到是谁打开了同一个文件。备份软件、杀毒软件、残留的 Excel 进程,是常见的几个对手。关于如何从设计上根本避免文件协作中出现这种冲突,笔者在「文件协作互斥控制基础知识」中做过总结;Excel 进程残留的问题,则整理在「C# 操作 Excel 导致 EXCEL.EXE 残留的问题」中。这里也附带说明一下,如果只是想知道「此刻是谁占用着」,比起 ProcMon,Process Explorer 的句柄搜索(Ctrl+F)会更快。3
5.5 「启动很慢」—— 大致定位时间消耗在何处
在列设置中添加 Duration 列,就能看到每个操作各自耗费的时间。此外,通过 Tools 菜单中的 Process Activity Summary 或 File Summary,可以按进程、按文件汇总操作次数与耗时。这足以用来大致定位「启动时进行了数万次注册表读取」「跨网络路径的访问一直等到超时」之类的问题。不过,深入分析 CPU 消耗在何处的专业性能剖析,并不是 ProcMon 的领域。如果拖慢速度的原因不是 I/O 而是计算,就应该交给 PerfView 与 dotnet-trace 来处理。
5.6 启动时、登录时的问题 —— 启动日志记录(Boot Logging)
对于「服务在登录之前就已失败」「注册到启动项的应用无法启动」等问题发生在手动启动 ProcMon 之前的情形,可以使用 Options 菜单中的 Enable Boot Logging。启用后,下次启动时从系统引导初期开始的事件都会被记录下来,再次启动 ProcMon 时会提示进行保存。启动时日志记录是 ProcMon 官方提供的功能,1 在涉及启动顺序、登录脚本的排查中,这是唯一的观察手段。
6. 日志的保存与交接 —— 在客户环境中采集的情形
在故障排查的实际工作中,只有客户那边才能复现问题的情况并不少见。ProcMon 的日志可以保存为 PML 文件,即便在另一台机器上打开,也能看到全部列和全部详情,因此「由客户采集、我方负责解析」这种分工是可行的。委托对方操作时,笔者通常整理成下面这样的步骤说明。
- 以管理员身份运行 Procmon.exe,并同意使用许可协议
- 启动后先用 Ctrl+E 停止抓取,再用 Ctrl+X 清除显示
- 用 Ctrl+E 开始抓取,复现问题操作
- 一旦复现成功(或出现错误),立即用 Ctrl+E 停止
- 通过 File > Save 保存,注意选择 All events 而非 Events displayed using current filter,以 PML 格式保存,压缩为 ZIP 后发送
关键在于第 5 步的「All events」。即便对方的画面上残留着 Filter,只要记录本身是全量的,我方就可以自由地重新筛选。对于复现耗时较长、或不知道何时会发生的问题,如果放任不管会持续消耗内存,因此至少要指定以下两者之一:启用 Filter > Drop Filtered Events,只记录目标进程,或者通过 File > Backing Files 将保存目标从虚拟内存切换为文件。如果不了解这两点就放任其运行一整晚,内存会被耗尽,导致 ProcMon 比排查对象本身先达到极限。
如果想实现自动化,也可以使用命令行开关。通过 /AcceptEula 抑制同意对话框、/BackingFile 指定记录目标文件、/Runtime 指定按秒数自动停止、/Terminate 终止正在运行的 ProcMon,组合这些开关就能实现「故障发生时,操作人员只需执行一个批处理即可留下证据」的形式。事先决定好故障发生时应采集哪些内容的思路,与崩溃转储采集和事件日志设计是相通的。
7. ProcMon 的局限性,以及与其他工具的搭配使用
ProcMon 是一款查看「操作时间序列」的工具,并非适用于所有类型的排查。本公司在排查工作中的分工如下。
| 工具 | 能看到的内容 | 用武之地 |
|---|---|---|
| Process Monitor | 文件、注册表、进程启动的时间序列 | 环境依赖型故障,配置、DLL、权限、锁定问题 |
| Process Explorer | 当前进程、句柄、DLL 的状态 | 追查占用文件的元凶、观察句柄数量3 |
| WinDbg + 转储 | 崩溃、挂起瞬间的内存与堆栈 | 异常、崩溃、假死的分析 |
| PerfView / dotnet-trace | CPU 采样、GC、内存分配 | “缓慢”问题的定量排查 |
| Application Verifier | API 误用、强制触发异常路径 | 出货前的异常路径测试 |
| Wireshark / pktmon | 数据包的内容 | 通信协议层面的排查4 |
以下三点是在边界上容易犹豫不决的地方。
- 网络: ProcMon 会记录 TCP/UDP 的连接、收发事件(哪个进程与何处通信),但看不到数据包的具体内容。协议层面的排查请交给 Wireshark 或 Windows 自带的 pktmon。4
- 内存: 「内存使用量持续增长」这类问题无法用 ProcMon 追踪。如果是托管堆,请进入判断是 GC 还是泄漏的流程;如果是句柄,则进入句柄泄漏排查的流程。
- 堆栈: 实际上 ProcMon 也会记录每个事件发出方的线程堆栈(双击事件 → Stack 标签页),只要设置好符号,就能在代码层面定位「是谁发出了这次文件访问」。到了这一步,就与 WinDbg 的世界连成一片,符号(PDB)的管理也开始发挥作用。
8. 结语 —— 「在阅读代码之前,先查看事实」
在环境依赖型故障排查中,最先应该做的既不是阅读代码,也不是建立假设,而是记录下实际发生了什么。ProcMon 正是通往这一目标的最短路径:安装只需一分钟,抓取只需几分钟,就能获得「触碰了哪个路径、按什么顺序、以什么权限、又在哪里失败」这样确凿的事实。只要掌握 Filter 的两个阶段(进程 → Result)、看似异常实则正常的 Result 的解读方法,以及以全部事件保存后再交接这三点,原本停滞在「开发机上无法复现」的排查工作,当天就能向前推进一步。
本公司承接尚不清楚复现条件的故障排查、仅在客户环境中发生的故障的证据采集流程整理,以及结合 ProcMon、WinDbg、PerfView 的原因分析等业务。即便是「日志中什么都没有显示,但程序就是无法运行」这样的阶段,我们也能提供协助。
相关文章
- 用 WinDbg + SOS 读取崩溃转储 —— 采集之后的实务分析入门
- 用 PerfView 与 dotnet-trace 定位”缓慢”问题 —— .NET 性能排查实务入门
- Windows 崩溃转储采集入门 - WER/ProcDump/WinDbg
- Windows DLL 名称解析机制 - 搜索顺序与 SxS
- 工业相机长期运行崩溃排查 - 句柄泄漏篇
参考资料
-
Microsoft Learn, Process Monitor - Sysinternals。关于 Process Monitor 是一款能够实时显示文件系统、注册表、进程/线程活动的监控工具,是 Filemon 与 Regmon 的后继产品,并具备非破坏性 Filter、线程堆栈记录、启动时日志记录等功能的说明。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Sysinternals Live。关于 Sysinternals Live 是一项无需下载工具、即可通过 live.sysinternals.com/
的 URL 或文件共享直接运行工具的服务的说明。 ↩ -
Microsoft Learn, Process Explorer - Sysinternals。关于 Process Explorer 能够显示进程打开的句柄和已加载的 DLL,并可用于搜索是哪个进程打开了特定文件或目录的说明。 ↩ ↩2
-
Microsoft Learn, Packet Monitor (Pktmon)。关于 Windows 内置的数据包抓取工具 Packet Monitor 的概述与用途的说明。 ↩ ↩2
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
用 WinDbg + SOS 解读崩溃转储 ── 采集之后的实务分析入门
本文说明如何用 WinDbg 与 SOS 扩展实际读取已采集的 Windows 崩溃转储。内容涵盖符号路径设置、以 !clrstack、!pe、!dumpheap -stat、!gcroot 追踪异常与内存泄漏的方法、原生崩溃的 !analyze -v,以及与 dotnet...
任务计划程序的任务不执行、以 0x1 结束 ── 原因排查与安全的运维设计
本文整理 Windows 任务计划程序的执行账户与登录类型、「不管用户是否登录都要运行」的含义、以 0x1 结束的典型原因、启用历史记录、防止多重启动、PowerShell 脚本的正确调用方式,直到把定期执行真正落实到运维上的设计方针。
WinForms/WPF应用的多语言化 ── resx、附属程序集与区域文化切换的实务
本文从实务角度系统梳理Windows桌面应用多语言化的要点:CurrentCulture与CurrentUICulture的区别、resx与附属程序集构成的资源机制、WinForms的Localizable属性、WPF的现实方案选择、运行时语言切换,以及排版、格式、RTL等内容。
CSV 不是「纯文本」──C# 业务应用中 CSV 实务(字符编码・Excel 兼容性・注入攻击防范)
梳理业务应用 CSV 读写中常见的事故模式──用 Split(',') 自行解析、无 BOM 的 UTF-8 导致 Excel 乱码、前导零丢失、CSV 注入攻击──并从实务角度讲解 RFC 4180 规则、.NET 中 Shift_JIS 的处理方式(CodePagesE...
不要用 using 包裹 HttpClient —— C# 业务应用的 HTTP 通信实务(创建模式・超时设计・重试)
C# 的 HttpClient 如果每次都用 using 创建会导致套接字耗尽,改成 static 又无法跟上 DNS 变更——本文从 Windows 业务应用的实务角度,整理这两大问题的成因,以及通过 PooledConnectionLifetime、IHttpClien...
常见问题
汇总了咨询这一主题时常见的问题。
- ProcMon 可以在生产环境中运行吗?
- 短时间的抓取在实际工作中很常见,但并不是无条件安全的。ProcMon 会加载驱动程序并记录大量事件,因此在事件发生量大的服务器上,会明显消耗 CPU 和内存。应对方法有三个:(1)在复现操作前一刻开始记录,操作后立即停止,将抓取时间压缩到最短;(2)如果需要长时间监控,可在 Filter 菜单中启用 Drop Filtered Events,不保留过滤条件之外的事件;(3)设置 Backing File,将记录目标指定为文件而非内存。此外,建议将其纳入与常规变更作业相同的审批流程,例如安排在业务时间之外执行,或在获取快照之后再执行。
- 事件太多,找不到目标行,应该如何缩小范围?
- 标准做法是首先用 Process Name 只对目标进程设置 Include,然后用 Result 缩小到异常类(NAME NOT FOUND、ACCESS DENIED 等)。一旦找到一行目标事件,就右键点击该行,通过弹出的 Include 或 Exclude 进行交互式的进一步缩小范围。反过来,「保存时仍带着过滤条件导致信息不足」的失败案例也不少,因此如果要将日志保存为文件交给他人,请记住 Filter 只是显示层面的筛选,应保存全部事件。另外,由于过滤设置在下次启动时也会被保留,当出现「什么都不显示」的情况时,请先通过 Filter 菜单的 Reset Filter 确认是否残留了上次的旧过滤条件。
- Result 列中出现的 BUFFER OVERFLOW 是 bug 或攻击的迹象吗?
- 不是。这与安全领域所说的缓冲区溢出攻击毫无关系,而是「所需数据比调用方准备的缓冲区更大,因此返回了所需大小」这样一次正常的 API 往返。许多 API 的设计是先用小缓冲区调用一次以获知所需大小,然后重新分配并再次调用,因此只要紧接着对同一路径出现了 SUCCESS,就没有问题。同样地,NAME NOT FOUND 大多也只是「在探索顺序的中途没有找到」,只要最终在某处成功(SUCCESS)了,就不算异常。异常类的 Result,只有确认「该操作的失败是否与应用的症状存在因果关系」之后,才能称之为真正的原因。
- Process Explorer 和 Process Monitor 应该如何区分使用?
- Process Monitor 是按时间顺序记录「操作流程(何时・哪个进程・对哪个路径・做了什么・结果如何)」的工具,而 Process Explorer 是查看「此刻的状态(哪个进程打开了哪个文件或 DLL、CPU 与内存的使用情况)」的工具。举例来说,如果想知道「这个文件删不掉,是被谁占用了」,用 Process Explorer 的句柄搜索最快;如果想知道「应用是何时、以何种顺序读取这个文件的」,则应该用 Process Monitor。实际工作中,建议将两者作为 Sysinternals Suite 常备待用,并记住「状态看 Process Explorer,历史看 Process Monitor」,就不会搞混了。
作者简介
本文作者的个人简介页面。
Go Komura
小村软件有限公司 代表
以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。