← 博客

2026年7月21日 · 6 分钟阅读

用 majorsilence-migrate 迁移 WinForms 应用

本页为译文。如与英文版有出入,以英文版为准。 English

majorsilence-migrate 是把 WinForms 解决方案自动迁移到 Majorsilence.Forms 的 CLI 工具。它最核心的设计 决策很容易被忽略,值得明确指出:它不解析语法树,也不解析符号。它是一个对原始源代码文本进行多遍处理的 文本/正则重写器——而这是有意为之。

为什么基于文本,而不是 Roslyn

引用该工具源码中的一句注释:“这是一个刻意基于文本的转换——它不解析语法树——这让它既快速,又能容忍 当前无法编译的文件。”

这种取舍换来了两样符号感知型工具无法提供的东西:

代价是:没有真正的跨项目符号解析。重写器不一定总能分辨一个裸的 Panel 引用指的是 System.Windows.Forms.Panel 还是你自己的同名类——它依赖的是命名空间前缀和 using/Imports 上下文。 实践中这很少产生歧义(WinForms 和 Telerik 的类型名都很有辨识度),而任何它不认识的东西都会被标记出来 供人工审查,而不是悄悄瞎猜。

可选的 Roslyn 引擎

对于真正有歧义的情况——同一个文件里,一个自定义类型与某个 WinForms/GDI+ 类型共用同一个裸名称—— 有一个可选启用的第二引擎:--engine roslyn。它使用 MSBuildWorkspace 和真正的符号解析来代替正则表达式, 并且是叠加在文本引擎之上而非取代它;在 Roslyn 模式下仍有若干遍处理保持为文本方式,因为它们从来就 不是符号解析问题。

它的取舍与默认引擎正好相反:它需要一个确实能通过 MSBuild 加载的解决方案或项目(裸目录或单个文件会回退到 文本引擎并给出警告);它慢上几个数量级,因为 MSBuild 求值占据了运行时间的大头;而且如果某个项目加载失败, 只有该项目的文件会回退到文本引擎——整个运行不会中止。如果根本找不到 MSBuild,整个运行会直接硬性失败, 而不是悄悄降级。

什么时候该用它: 在用默认的 --engine text 跑完第一遍之后,针对一个已经能干净加载的项目,并且你在 diff 中看到了某个具体、已确认的名称冲突情况。而对于一个庞大、可能半残的遗留代码库的首次处理,默认的 文本引擎仍然是正确的工具。

接下来

参阅仓库中的 MIGRATION.md,了解逐遍处理的完整细目; 以及 COMPATIBILITY_MATRIX.md,了解迁移后的 代码编译通过之后,哪些功能是真正已实现的。