WinMerge 2.16.58.2 是 Windows 上的开源文件与目录对比工具,x64 绿色版压缩包 24493933 字节,解开 472 个文件共 81636621 字节。
它要解决的事情一句话能说完:两份东西到底差在哪。改过一版配置不知道动了什么 / 两个人各写了一份文档要合并 / 发布前对比生产目录和本地构建目录,这 3 个场景靠肉眼翻是行不通的。
这次用三组真实数据把它压了一遍:520 个文件的目录对 520 个文件、10 万行的文本对 10 万行、一份 844 字节的脚本对它的 937 字节修改版,另外量了窗口从启动到出现的毫秒数。
压缩包解开是 472 个文件
GitHub 上的 x64 exe 包是 24493933 字节,用 7-Zip 解压得到 472 个文件、32 个目录,合计 81636621 字节。主程序只占其中一小部分。
| 项目 | 值 | 说明 |
|---|---|---|
| 压缩包 | 24493933 字节 | x64 exe 版,无需安装 |
| 解压后 | 81636621 字节 | 472 个文件 / 32 个目录 |
| 主程序 WinMergeU.exe | 6747456 字节 | Unicode 版本,日常用这个 |
| 中文帮助 WinMerge.chm | 1080818 字节 | 占解压总量约 1.3% |
| 版本号 | 2.16.58.2 | 文件属性里的 FileVersion |
大头是语言包和帮助文件
472 个文件里有一大半是 Languages 目录下的翻译文件和 Docs 下的 chm 手册,英语 / 法语 / 希伯来语各有一份 1 MB 上下的手册。只留主程序和 MergePlugins,整个目录能压到 20 MB 以内。
解压即用,不往系统目录写东西
把 WinMerge 目录放到 D 盘的临时路径下直接双击就能跑,没有安装步骤。跑完之后目录里还是原来那 472 个文件,没有多出配置文件,说明默认设置编译在程序里,改过选项才会落盘。
窗口 496 毫秒出来
三次启动分别测了空窗口、10 万行文本对比、目录对比,从 CreateProcess 到窗口可见是 496、507、515 毫秒。三者相差 19 毫秒,这段时间花在加载程序本身,不在处理数据。
| 场景 | 首帧(毫秒) |
|---|---|
| 直接启动,无参数 | 496 |
| 带两个 10 万行文件启动 | 507 |
| 带两个 520 项目录启动 | 515 |
| 三者最大差值 | 19 |
首帧只是外壳,不代表比完了
窗口 496 毫秒画出来的是框架,列表内容随后分批填入。520 个文件的那次,截图前已经全部填满,但填满的时刻没有单独计时,所以这个数只能说明程序起来了,不能当成比对完成的耗时。
6747456 字节的原生程序
主程序是 C++ 写的,没有 .NET 运行时也没有 Electron 那层壳。同样功能的跨平台方案通常要 2 到 3 秒起窗口,天天用的工具上 496 毫秒和 3 秒的差别是能感觉到的。
520 个文件对 520 个文件
造了两个目录:A 有 520 个文件,B 有 520 个文件,其中 500 个同名,50 个内容被改过,20 个只在 A,20 个只在 B。用 /r 参数递归比较,界面把 520 行全部列了出来。
| 类别 | 数量 | 界面标记 |
|---|---|---|
| 左侧文件总数 | 520 个 | 与目录实际一致 |
| 右侧文件总数 | 520 个 | 与目录实际一致 |
| 同名文件 | 500 个 | 其中 450 个内容相同 |
| 内容不同 | 50 个 | 文本文件不同 |
| 只在左侧 | 20 个 | A 列有、B 列空 |
| 只在右侧 | 20 个 | A 列空、B 列有 |
| 需要人工看的行 | 90 行 | 50 + 20 + 20 |
| 左侧目录总体积 | 12574 字节 | 520 个文件合计 |
| 右侧目录总体积 | 11874 字节 | 520 个文件合计 |

同名文件按内容判而不按时间判
50 个被改过的文件时间戳和大小都不一样,工具仍然逐个读内容比对,所以内容相同但时间戳不同的 450 个文件被正确归到无差异一类,不会误报。这一点和按时间戳同步的工具正好相反。
520 行全列出来,不折叠
界面没有把相同的 450 行藏起来,而是按差异优先排序,520 行都在,差异行带图标和「文本文件不同」的文字。需要人工确认的是 90 行,占全部行的 17%,扫一遍列表就能定位。
10 万行对 10 万行
两个文件各 10 万行,1785712 字节对 1785927 字节,每隔 1000 行改一处,一共 100 处差异。打开后第一屏就能看到第 1 行的差异被标成整行黄色。
| 指标 | 值 |
|---|---|
| 左侧文件 | 1785712 字节 / 100000 行 |
| 右侧文件 | 1785927 字节 / 100000 行 |
| 差异处 | 100 行,每 1000 行一处 |
| 差异密度 | 0.1% |
| 首帧 | 507 毫秒 |
两栏左侧都有行号
滚动时两栏的行号同步走,10 万行的文件如果只改了几行,靠行号定位比翻页可靠。第一处差异在第 1 行,第 1000 行还有一处,按行号直接跳比拖着滚动条准。
首屏就能判断规模
打开 1785712 字节的文件,第一屏显示的差异密度直接告诉你改动是集中在开头还是散布全篇。100 处差异摊在 10 万行里,密度只有 0.1%,靠眼睛翻是找不到的。
一份脚本与它的改版
拿一个真实的 Python 脚本做对照:原版 844 字节,改过的版本 937 字节,改动散布在 6 个位置,包括一个常量、一个函数签名、一处条件、一个循环元组和一行打印。
| 位置 | 改动 |
|---|---|
| 原版 / 改版体积 | 844 字节 / 937 字节 |
| 第 5 行 | LIMIT 从 5000 改成 10000 |
| 第 11 行 | rows 初始化多了一句注释 |
| 第 20 行 | filter_city 增加 strict 参数 |
| 第 22 行 | 条件里多一个 and 判断 |
| 第 46 行 | 城市元组多一个深圳 |
| 第 49 行 | 打印里加上 limit |
| 改动总数 | 6 处 |

差异块用两层颜色
整行改动的背景是黄色,行内被动过的字符用更深的底色单独标出,只在一边出现的内容另一侧留空。6 个改动位置在一屏里看得清清楚楚,937 字节的文件不用滚动就到底。
改一行不牵连上下文
第 22 行加了一个 and 条件,它后面 3 行没有跟着误报成差异。这个能力决定了审阅改动时的信噪比,否则一处改动会被放大成一整段红,6 处改动看起来像 60 处。
命令行怎么调
命令行参数比界面点选快,尤其是每天要开同样的两组目录。
| 命令 | 作用 |
|---|---|
| WinMergeU.exe /r D:\cmp\A D:\cmp\B | 递归比较两个目录,520 行一次列全 |
| WinMergeU.exe D:\cmp\big_a.txt D:\cmp\big_b.txt | 比较两个文件 |
| WinMergeU.exe /? | 会弹出窗口,不是命令行帮助 |
REM 递归比较两个目录,520 行一次列全
WinMergeU.exe /r D:////cmp////A D:////cmp////B
REM 比较两个文件,只看一层
WinMergeU.exe D:////cmp////big_a.txt D:////cmp////big_b.txt
/r 决定要不要往下钻
带了 /r 才会递归进子目录。这次两个目录的 520 个文件都在一层,所以 2 种写法结果一样,目录有嵌套时必须带,否则子目录里的差异根本不会出现。
/? 会直接开一个窗口
习惯性敲 WinMergeU.exe /? 想看帮助,结果它把帮助文档当文件打开,弹出 1 个窗口停在那里,脚本里这么写会一直挂住。要拿帮助直接看 Docs 目录下的 chm,6 个翻译版本都在那个目录。
几个真踩过的点
下面三条都在这次测试里真实出现,不是猜的。
| 现象 | 原因 | 处理 |
|---|---|---|
| 7z 解压报 Data Error | 下载中断,包只有 7634944 字节 | 重新下到 24493933 字节,先 7z t 再解压 |
| /? 之后命令行停住 | 帮助被当成文件打开 | 不要用 /?,直接看 Docs 里的 chm |
| 界面全是中文 | 跟随系统区域设置 | 想换语言改 Languages 目录或在选项里切换 |
压缩包必须校验完整性
第一个下载的包只有 7634944 字节,7z 能列出目录但解到一半报错,主程序根本没出来。完整包是 24493933 字节,差了三倍多。先跑 7z t 再解压,比解完发现少文件省时间。
中文界面不是 bug
程序按系统区域自动选语言,中文系统上菜单就是中文的,和文档里的英文截图对不上。功能位置完全一样,对照英文教程时知道这一点就行,Languages 目录就是用来切换的。
列表里排着 6 列
目录比较的列表把每个文件摊成 6 列:文件名、所在文件夹、比较结果、左日期、右日期、扩展名。520 行数据在这 6 列里一眼能看出差异落在哪一侧。
| 列名 | 示例值 | 用途 |
|---|---|---|
| 文件名 | f0000.txt | 带红绿图标,图标颜色即差异类型 |
| 文件夹 | A 或 B | 单边文件在这一列标出属于哪一侧 |
| 比较结果 | 文本文件不同 | 50 个改动全部是这一种取值 |
| 左日期 | 2026/10/26 22:52:36 | A 侧的最后修改时间 |
| 右日期 | 2026/10/26 22:52:35 | B 侧的最后修改时间,与左并排对照 |
| 扩展名 | txt | 按类型过滤时用这一列 |
两个日期并排就是为了看时间差
2540 像素宽的窗口里,左右两列时间戳并排显示,只差 1 秒的属于同一批生成的文件,差得多的通常是被单独改过的那 50 个。时间戳本身不参与判定,但排在两列里能当线索用。
520 行里靠图标分三类
差异图标有 3 种形态:整行红、左侧红右侧空、左侧空右侧红。50 个内容改动和左右各 20 个单边文件靠这 3 种图标就能分流,不用逐行读文字。
先比目录,再比文件
实际用起来的顺序是固定的:先用目录比较定位到具体哪几个文件有问题,再逐个打开看内容差在哪。跳过第一步直接从 520 个文件里挑,等于没有工具。
| 步骤 | 动作 | 这一轮拿到的结果 |
|---|---|---|
| 1 | 给两个目录路径,带 /r | 520 行列表,90 行需要看 |
| 2 | 按图标过滤出内容不同的 50 个 | 范围从 520 缩到 50,缩了 10 倍 |
| 3 | 双击单个文件打开两栏对比 | 6 处改动的文件一屏看完 |
第 2 步决定效率
520 个文件里真正要处理的是 50 个,占不到一成;两个目录的总体积一个是 12574 字节、另一个 11874 字节,差 700 字节,全部落在那 50 个改动文件里。目录比较的价值就在这一次收窄,把 520 行的排查变成 50 行的清单。
第 3 步才需要读内容
打开单个文件时才有行级高亮和行内字符标注,目录列表里看不到这些。所以两个视图的分工很明确:列表负责定位,文本视图负责判断。
什么场景值得上
需要回答「这两份东西差在哪」的时候,它比命令行 diff 直观,比在线工具安全。520 个文件的目录一次列全,这是文本 diff 做不到的。
| 场景 | 合适度 | 说明 |
|---|---|---|
| 发布前对比构建目录 | 高 | 520 项目录一次列全,差异按行标色 |
| 审阅配置改动 | 高 | 行级高亮,改动的字符单独标底色 |
| 对比两份文档 | 中 | 纯文本好用,Word 文档要先转成 txt |
| 二进制文件对比 | 低 | 只能看到字节差异,可读性差 |
| 纳入 CI 自动化 | 低 | 没有无头模式,退出码拿不到差异数 |
它不做流水线里的那一步
能看能改,但没有无头模式也没有生成报告的命令行开关,所以接不进自动门禁。流水线里的差异判断交给 diff 或 git diff 这 2 条命令,这个工具的位置在人工审阅,处理几十行差异最舒服,再多就该上脚本。
授权与费用
GPLv2 许可,个人和商业环境都不收费,源码在 GitHub 上,2 个发行包都在同一个页面。安装包和绿色包在同一个 release 页面,选 x64-exe.zip 那一项就是不用安装的版本,双击解压出来的 exe 直接跑。






