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.exe6747456 字节Unicode 版本,日常用这个
中文帮助 WinMerge.chm1080818 字节占解压总量约 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 个文件合计
WinMerge 2.16.58.2 文本对比窗口:左侧 report_a.py 右侧 report_b.py,6 处改动整行标黄,行内改动字符底色更深

同名文件按内容判而不按时间判

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 处
WinMerge 目录比较结果:左右各 520 个文件逐行列出,比较结果列为「文本文件不同」,A 列与 B 列时间戳并排

差异块用两层颜色

整行改动的背景是黄色,行内被动过的字符用更深的底色单独标出,只在一边出现的内容另一侧留空。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:36A 侧的最后修改时间
右日期2026/10/26 22:52:35B 侧的最后修改时间,与左并排对照
扩展名txt按类型过滤时用这一列

两个日期并排就是为了看时间差

2540 像素宽的窗口里,左右两列时间戳并排显示,只差 1 秒的属于同一批生成的文件,差得多的通常是被单独改过的那 50 个。时间戳本身不参与判定,但排在两列里能当线索用。

520 行里靠图标分三类

差异图标有 3 种形态:整行红、左侧红右侧空、左侧空右侧红。50 个内容改动和左右各 20 个单边文件靠这 3 种图标就能分流,不用逐行读文字。

先比目录,再比文件

实际用起来的顺序是固定的:先用目录比较定位到具体哪几个文件有问题,再逐个打开看内容差在哪。跳过第一步直接从 520 个文件里挑,等于没有工具。

步骤动作这一轮拿到的结果
1给两个目录路径,带 /r520 行列表,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 直接跑。