← blog

21 juillet 2026 · 6 min de lecture

Migrer une application WinForms avec majorsilence-migrate

Cette page est une traduction. En cas de divergence, la version anglaise fait foi. English

majorsilence-migrate est l’outil en ligne de commande qui automatise le passage d’une solution WinForms vers Majorsilence.Forms. Sa décision de conception centrale passe facilement inaperçue et mérite d’être dite explicitement : il ne construit pas d’arbre syntaxique et ne résout pas les symboles. C’est un réécriveur textuel à base d’expressions régulières, en plusieurs passes, sur le texte source brut — et c’est voulu.

Pourquoi textuel, et non Roslyn

Extrait du commentaire présent dans le code source de l’outil : « Il s’agit d’une transformation délibérément textuelle — elle n’analyse pas l’arbre syntaxique — ce qui la garde rapide et tolérante aux fichiers qui ne compilent pas actuellement. »

Ce compromis apporte deux choses qu’un outil conscient des symboles ne peut pas offrir :

Le prix à payer : pas de véritable résolution de symboles entre projets. Le réécriveur ne peut pas toujours savoir si une référence nue à Panel désigne System.Windows.Forms.Panel ou votre propre classe du même nom — il s’appuie à la place sur le préfixe d’espace de noms et sur le contexte des using/Imports. En pratique, c’est rarement ambigu (les noms de types WinForms et Telerik sont reconnaissables), et tout ce qu’il ne reconnaît pas est signalé pour revue manuelle plutôt que deviné en silence.

Le moteur Roslyn optionnel

Pour le cas réellement ambigu — un type personnalisé partageant un nom nu avec un type WinForms/GDI+ dans le même fichier — il existe un second moteur, à activer explicitement : --engine roslyn. Il utilise MSBuildWorkspace et une vraie résolution de symboles au lieu d’expressions régulières, par-dessus le moteur textuel plutôt qu’à sa place ; plusieurs passes restent textuelles même en mode Roslyn, parce qu’elles n’ont jamais été des problèmes de résolution de symboles.

Les compromis sont à l’inverse de ceux du moteur par défaut : il lui faut une solution ou un projet qui se charge réellement via MSBuild (un simple répertoire ou un fichier isolé retombe sur le moteur textuel avec un avertissement), il est plus lent de plusieurs ordres de grandeur parce que l’évaluation MSBuild domine l’exécution, et si un projet échoue à se charger, seuls les fichiers de ce projet retombent sur le moteur textuel — l’exécution ne s’interrompt pas. Si MSBuild lui-même est introuvable, l’exécution entière échoue franchement plutôt que de se dégrader en silence.

Quand y recourir : après une première passe avec le moteur par défaut --engine text, sur un projet qui se charge déjà proprement, si vous constatez dans le diff un cas précis et confirmé de collision de noms. Pour la passe initiale sur une grande base de code héritée, éventuellement à moitié cassée, le moteur textuel par défaut reste le bon outil.

La suite

Voir MIGRATION.md dans le dépôt pour le détail passe par passe, et COMPATIBILITY_MATRIX.md pour ce qui est réellement implémenté une fois que votre code migré compile.