mcpField
D
dotnet-wpf-migration

dotnet-wpf-migration

github.com/wshaddix開発8686 回インストール35 週間前に更新
リポジトリ

dotnet-wpf-migration について

dotnet-wpf-migrationは、Windowsデスクトップアプリを最新化するチーム向けの移行ガイドスキルです。最新の.NETへのアップグレードや、WPF、WinUI 3、Uno Platform間の移行を扱い、プロジェクトの制約に応じた経路を示します。

主な機能

  1. 01WPF .NET Frameworkから.NET 8+へ移行
  2. 02WinForms .NET Frameworkから.NET 8+へ移行
  3. 03WPFからWinUI 3への移行
  4. 04WPFからUno Platformへの移行
  5. 05UWPの移行経路
  6. 06移行工数とリスクの比較

活用シーン

  1. 01UIを維持してWPFアプリを更新
  2. 02WinFormsアプリのランタイムを最新化
  3. 03WPFビューをWinUI 3向けに書き換え
  4. 04WPFコードベースをクロスプラットフォーム化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wshaddix/dotnet-skills --skill dotnet-wpf-migration

インストール後、Claude Code で/dotnet-wpf-migrationを入力して読み込まれたか確認します。

詳細

dotnet-wpf-migration

Windows デスクトップアプリケーション向けの、状況に応じた移行ガイダンスです。WPF .NET Framework から .NET 8 以降への移行、WPF から WinUI 3 への移行(Windows 限定のモダナイズ)、WPF から Uno Platform への移行(クロスプラットフォーム)、WinForms .NET Framework から .NET 8 以降への移行、UWP から WinUI 3 への移行、UWP から Uno Platform への移行(相互参照)、およびプロジェクトの制約に基づいて適切な移行先を選ぶための判断マトリックスを扱います。

バージョンの前提: .NET 8.0 以降をベースラインとします(現行の LTS)。自動移行には dotnet-upgrade-assistant を使用します。該当する場合は、.NET 9 の機能を明記します。

対象範囲の境界: このスキルでは、デスクトップフレームワーク間、および .NET Framework から最新の .NET への移行パスを扱います。各フレームワークのパターン(WPF のモダンな開発、WinUI、WinForms のモダンな開発)は、それぞれのフレームワーク用スキルで扱います。フレームワーク選択の判断ツリーは [skill:dotnet-ui-chooser] で扱います。

対象外: WPF .NET 8 以降の開発パターンについては、[skill:dotnet-wpf-modern] を参照してください。WinUI 3 の開発パターンについては、[skill:dotnet-winui] を参照してください。WinForms .NET 8 以降の開発パターンについては、[skill:dotnet-winforms-basics] を参照してください。Uno Platform の開発パターンについては、[skill:dotnet-uno-platform] を参照してください。フレームワーク選択の判断ツリーについては、[skill:dotnet-ui-chooser] を参照してください。デスクトップのテストについては、[skill:dotnet-ui-testing-core] を参照してください。

相互参照:WPF .NET 8 以降のパターンについては [skill:dotnet-wpf-modern]、WinUI 3 のパターンについては [skill:dotnet-winui]、WinForms .NET 8 以降のパターンについては [skill:dotnet-winforms-basics]、Uno Platform のパターンについては [skill:dotnet-uno-platform]、フレームワーク選択については [skill:dotnet-ui-chooser]、デスクトップのテストについては [skill:dotnet-ui-testing-core] を参照してください。


移行パスの概要

現在のフレームワークと移行先の目標に基づいて、移行パスを選択してください。各パスでは、作業量、リスク、機能向上の度合いが異なります。

現在の環境移行先作業量リスク選択する状況
WPF .NET FrameworkWPF .NET 8+低~中低既存の UI を維持しながらランタイムを最新化する
WPF .NET FrameworkWinUI 3高中最新の Windows UI、タッチ/ペン、Fluent が必要
WPF .NET FrameworkUno Platform高中~高クロスプラットフォーム対応が必要
WinForms .NET FrameworkWinForms .NET 8+低低既存の UI を維持しながらランタイムを最新化する
UWPWinUI 3中中Windows 限定を維持しながらランタイムを最新化する
UWPUno Platform中~高中UWP からのクロスプラットフォーム対応が必要

WPF .NET Framework から .NET 8 以降へ

最もリスクの低い移行パスです。既存の XAML とコードビハインドをそのまま維持しながら、パフォーマンスの向上、DI のサポート、サイドバイサイド展開が可能な最新の .NET に移行できます。

dotnet-upgrade-assistant を使用する

.NET Upgrade Assistant は、移行の大部分を自動化します。

# Install the upgrade assistant
dotnet tool install -g upgrade-assistant

# Analyze the project first (non-destructive)
upgrade-assistant analyze MyWpfApp.sln

# Upgrade the project
upgrade-assistant upgrade MyWpfApp.sln

Upgrade Assistant が対応する項目:

  • .csproj を従来の形式から SDK 形式に変換
  • packages.config から PackageReference への移行
  • TFM を net8.0-windows に変更
  • AssemblyInfo.cs のプロパティを .csproj に移動
  • 一般的な API の置き換えと名前空間の更新

手作業が必要な項目:

  • App.config の設定を appsettings.json または Host ビルダーの構成に移行
  • Settings.settings/My.Settings(VB.NET)の移行
  • サードパーティ製コントロールライブラリの更新(ベンダーによる .NET 8 への対応状況を確認)
  • WCF クライアント参照(CoreWCF を使用するか、gRPC/REST に移行)
  • COM 相互運用の調整(System.Runtime.InteropServices の構文の違い)
  • カスタム MSBuild ターゲットとビルドスクリプト
API の互換性

ほとんどの WPF API は、.NET Framework と .NET 8+ で同一です。主な違いは次のとおりです。

領域.NET Framework.NET 8+対応
クリップボードClipboard.SetText()同じ API変更なし
印刷PrintDialog、PrintVisual同じ API変更なし
BitmapEffect非推奨(ソフトウェアレンダリング)削除Effect / ShaderEffect を使用
DrawingContext.PushEffect利用可能削除ShaderEffect を使用
XPS ドキュメントSystem.Windows.XpsNuGet パッケージが必要System.Windows.Xps の PackageReference を追加
音声合成System.SpeechNuGet パッケージが必要System.Speech の PackageReference を追加
NuGet パッケージの更新

移行後、NuGet パッケージを .NET 8 対応バージョンに更新します。

# List outdated packages
dotnet list package --outdated

# Update packages (one at a time for safer migration)
dotnet add package Newtonsoft.Json --version 13.*
dotnet add package MaterialDesignThemes --version 5.*

一般的なパッケージの置き換え:

  • Unity コンテナー -> Microsoft.Extensions.DependencyInjection(組み込み)
  • Autofac -> 最新版に更新(.NET 8 に対応)
  • log4net / NLog -> Serilog または NLog プロバイダーとともに Microsoft.Extensions.Logging の利用を検討
  • EntityFramework(EF6) -> Microsoft.EntityFrameworkCore 8.x
破壊的変更のチェックリスト
  • 高 DPI の既定の動作が変更されました。 .NET 8 WPF は、既定で PerMonitorV2 DPI 認識を有効にします(.NET Framework のような SystemAware ではありません)。
  • Null 許容参照型。 新しいプロジェクトでは NRT が有効になります。既存のコードで警告が発生する場合があります。まず <Nullable>disable</Nullable> で警告を抑制し、その後、段階的に修正してください。
  • 暗黙的な using。 新しい SDK スタイルのプロジェクトでは、暗黙的な using が有効になります。既存の using ステートメントと競合する場合があります。必要に応じて <ImplicitUsings>disable</ImplicitUsings> で無効にしてください。
  • アセンブリの読み込み。 アセンブリの分離には、AppDomain の代わりに AssemblyLoadContext を使用します。AppDomain.CreateDomain を使用するプラグインアーキテクチャは、再設計が必要です。
  • ランタイムの動作。 .NET 8 の GC は、Gen0/Gen1 コレクションをより積極的に実行します。ファイナライザーに依存するコードの動作が異なる場合があります。

移行後の WPF パターン(Host ビルダー、MVVM Toolkit、最新の C#)については、[スキル:dotnet-wpf-modern] を参照してください。


WPF から WinUI 3 へ

Fluent Design、タッチ/ペン入力、Windows 11 との統合(ウィジェット、Mica)、または最新の .NET での UWP スタイル API など、最新の Windows ネイティブ UI が必要な場合に移行します。これは部分的な書き換えです。XAML の概念は引き継げますが、API と名前空間は異なります。

この移行が適している場合
  • アプリケーションがWindows 専用であり、今後も Windows 専用である
  • 最新のFluent Designコントロール、タッチ/ペンのサポート、または Windows 11 の機能が必要である
  • チームがXAML の書き換えに労力をかける意向がある
  • アプリケーションが積極的に開発されており、継続的な機能開発が行われている(投資に見合う)
代替案を検討する場合
  • クロスプラットフォームが必要な場合 -> 代わりに Uno Platform へ移行します(WinUI XAML サーフェス)
  • アプリケーションが保守モードの場合 -> 代わりに WPF .NET 8+ へ移行します(作業量を抑えられます)
  • WPF Fluent テーマ(.NET 9+)で十分な場合 -> ThemeMode = ThemeMode.System を指定して WPF .NET 8+ を継続します
XAML の違い
WPF XAMLWinUI 3 XAML備考
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"同じ URI(ただし、System.Windows ではなく Microsoft.UI.Xaml の型に解決されます)xmlns の変更はありませんが、実行時の型は異なります
{Binding Path=Name}{x:Bind Name, Mode=OneWay}x:Bind を推奨します(コンパイル済みで、型安全です)
DataContext バインディングコードビハインドのプロパティ + x:Bindx:Bind はコードビハインドを参照します
Window は System.Windows.Window を継承しますWindow は Microsoft.UI.Xaml.Window を継承します基底クラスと API が異なります
UserControlUserControl(Microsoft.UI.Xaml 名前空間)概念は同じですが、名前空間が異なります
TargetType を指定した Style同じ同じように機能します
DataTemplatex:Bind には x:DataType が必要ですコンパイル済みバインディングに必須です
ContextMenuMenuFlyoutコントロールの種類が異なります
StatusBar組み込みの同等機能はありませんカスタムの CommandBar または InfoBar を使用します
RibbonControl組み込みの同等機能はありませんNavigationView + CommandBar を使用します
移行戦略
  1. 既存の WPF プロジェクトと並行して、新しい WinUI 3 プロジェクトを作成します
  2. まず共有ロジックを移行します -- モデル、サービス、ViewModel(MVVM Toolkit を使用している場合は、どちらでも動作します)
  3. ビューを段階的に移行します -- シンプルなページから始め、次に複雑なページに進みます
  4. WPF 固有のコントロールを WinUI の同等機能に置き換えます(上の表を参照)
  5. コンパイル時の安全性を確保するため、データバインディングを {Binding} から {x:Bind} に更新します
  6. Windows 統合機能(通知、ライフサイクル、ファイルの関連付け)をテストします
  7. デプロイモデルを選択します -- MSIX(アプリ ID)またはアンパッケージ(xcopy)

WinUI 3 のパターンとプロジェクトのセットアップについては、[skill:dotnet-winui] を参照してください。


WPF から Uno Platform へ

WPF のコードベースをクロスプラットフォームに展開する必要がある場合に移行します。Uno Platform は WinUI の XAML API サーフェスを使用するため、WPF の XAML スキルの一部は引き継げますが、移行には WinUI の XAML パターンへの適応が必要です。

この移行が適している場合
  • アプリケーションを複数のプラットフォーム(Windows、macOS、Linux、Web、モバイル)で実行する必要がある
  • チームに WinUI XAML サーフェスにも活用できるWPF/XAML の専門知識がある
  • クロスプラットフォームへの適応(プラットフォーム固有の動作、レスポンシブなレイアウト)に投資する意思がある
代替案を検討する場合
  • Windows 専用の場合 -> WinUI 3 に移行します(よりシンプルで、クロスプラットフォーム対応のオーバーヘッドがありません)
  • アプリケーションがメンテナンスモードの場合 -> WPF .NET 8+ に移行します(最も手間が少なくて済みます)
  • チームにWeb のスキルがある場合 -> Web 配信には Blazor を検討します
移行方法

Uno Platform は WinUI API サーフェスを使用するため、WPF から Uno Platform への移行は、WPF から WinUI 3 への移行と似ていますが、クロスプラットフォームに関する考慮事項が追加されます。

  1. 目的のターゲットプラットフォームを指定して、Uno Platform プロジェクトを作成します
  2. ViewModel とサービスを移行します -- これらはプラットフォームに依存しません
  3. XAML を WinUI の構文に適応させます(WPF から WinUI への移行と同じ変更です)
  4. 条件付きコンパイルまたは Uno のプラットフォーム拡張機能を使用して、プラットフォーム固有の機能に対応します
  5. Windows 専用 API をクロスプラットフォームの代替機能(ファイルダイアログ、通知など)に置き換えます
  6. 各ターゲットプラットフォームをテストします -- Skia とネイティブのターゲットでは、レンダリングや動作が異なる場合があります
一般的なパターンに対応する Uno Extensions

Uno Extensions は、一般的な WPF パターンに代わるクロスプラットフォームの機能を提供します。

WPF のパターンUno Extensions の代替機能
カスタムナビゲーションUno.Extensions.Navigation
手動での DI セットアップUno.Extensions.DependencyInjection(MS DI をラップします)
appsettings.json の設定Uno.Extensions.Configuration
手動での HTTP クライアントUno.Extensions.Http(Refit を使用する型付きクライアント)
手動でのシリアル化Uno.Extensions.Serialization

Uno Platform の開発パターンについては、[skill:dotnet-uno-platform] を参照してください。ターゲットごとのデプロイ方法については、[skill:dotnet-uno-targets] を参照してください。


WinForms .NET Framework から .NET 8+

WPF の移行と同様ですが、WinForms はプロジェクト構造がそれほど複雑ではないため、通常はより簡単です。

dotnet-upgrade-assistant を使用する
# Analyze first
upgrade-assistant analyze MyWinFormsApp.sln

# Upgrade
upgrade-assistant upgrade MyWinFormsApp.sln

アップグレードアシスタントが処理する内容:

  • .csproj を <UseWindowsForms>true</UseWindowsForms> を含む SDK スタイルに変換
  • TFM を net8.0-windows に変更
  • packages.config を PackageReference に変換
  • AssemblyInfo.cs をプロジェクトプロパティに移行

手動作業が必要な内容:

  • App.config / Settings.settings の移行
  • My.Settings(VB.NET)を最新の構成に移行
  • サードパーティ製コントロールライブラリの更新(一部の WinForms コントロールは .NET 8 をサポートしていない場合があります)
  • Crystal Reports などのレガシーなレポートツール(代替手段を検討してください)
  • COM 相互運用の調整
デザイナーの互換性

WinForms デザイナーファイル(.Designer.cs)は通常、問題なく移行できます。.NET 8+ 用の Visual Studio WinForms デザイナーは完全にサポートされています。

既知のデザイナーの問題:

  • カスタムデザイナーシリアライザーの更新が必要な場合があります
  • 一部のサードパーティ製コントロールは .NET 8 デザイナーで描画されない場合があります
  • DPI 非対応のデザイナーモードは .NET 9+ で利用できます(<ForceDesignerDPIUnaware>true</ForceDesignerDPIUnaware>)
移行後のモダン化

.NET 8+ に移行した後は、最新のパターンを段階的に取り入れることを検討してください:

  • 依存関係の注入を追加:Host ビルダーを使用します([skill:dotnet-winforms-basics] を参照)
  • 同期呼び出しを置き換え:async/await を使用します
  • 高 DPI を有効化:PerMonitorV2 モードを使用します
  • ダークモードを有効化(.NET 9+ では試験段階です)

WinForms .NET 8+ のパターンについては、[skill:dotnet-winforms-basics] を参照してください。


UWP から WinUI 3 へ

UWP の自然な移行先です。WinUI 3 は同じ XAML API サーフェスを使用しますが、名前空間が変更されています。

名前空間の変更

主な移行作業は、名前空間を Windows.UI.* から Microsoft.UI.* に更新することです:

UWP の名前空間WinUI 3 の名前空間
Windows.UI.XamlMicrosoft.UI.Xaml
Windows.UI.Xaml.ControlsMicrosoft.UI.Xaml.Controls
Windows.UI.Xaml.MediaMicrosoft.UI.Xaml.Media
Windows.UI.CompositionMicrosoft.UI.Composition
Windows.UI.TextMicrosoft.UI.Text

そのまま維持するもの: Windows.Storage、Windows.Networking、Windows.Security、Windows.ApplicationModel、Windows.Devices — これらの WinRT API は変更されません。

アプリモデルの違い
項目UWPWinUI 3
アプリのライフサイクルCoreApplication + 中断Windows App SDK の AppInstance
ウィンドウ管理Window.Current(シングルトン)ウィンドウ参照を手動で追跡
ディスパッチャーCoreDispatcher.RunAsyncDispatcherQueue.TryEnqueue
バックグラウンドタスク組み込み、パッケージ ID が必要MSIX では利用可能、なしの場合は制限あり
ファイルアクセスマニフェストによる広範な機能標準の Win32 ファイルアクセス + StorageFile
Store APIWindows.Services.Store同じ(引き続き利用可能)
移行手順
  1. 新しい WinUI 3 プロジェクトを作成:Windows App SDK テンプレートを使用します
  2. ソースファイルをコピーし、名前空間を更新します(Windows.UI.Xaml から Microsoft.UI.Xaml)
  3. 非推奨の API を置き換えます(Window.Current を手動追跡に、CoreDispatcher を DispatcherQueue に置き換えます)
  4. MSIX マニフェストを更新します(UWP 形式から Windows App SDK 形式へ)
  5. 機能を移行します — 機能宣言を確認して更新してください
  6. NuGet パッケージを更新し、Windows App SDK 対応バージョンにします
  7. Windows との統合をテストします — 通知、バックグラウンドタスク、ファイルの関連付けの動作が異なる場合があります

UWP の .NET 9 プレビュー移行パス: Microsoft は、プレビューとして .NET 9 での UWP サポートを発表しました。WinUI 3 への完全な移行にコストがかかりすぎる場合、これにより UI フレームワークを移行せずに、UWP アプリで最新の .NET ランタイム機能を利用できます。

WinUI 3 の開発パターンについては、[skill:dotnet-winui] を参照してください。


UWP から Uno Platform への移行

UWP のコードベースを活用してクロスプラットフォームに対応する必要がある場合に適しています。Uno Platform は WinUI XAML API サーフェスを実装しているため、UWP からのクロスプラットフォーム移行先として最も自然な選択肢です。

Uno Platform は UWP XAML の基盤である WinUI XAML API サーフェスを使用するため、他のクロスプラットフォームフレームワークに移行する場合と比べて、多くの UWP コードを少ない変更で引き継げます。

  • XAML ファイルは、最小限の変更で動作することがよくあります(Uno は x:Bind、x:Load などをサポートしています)
  • ViewModel とサービスはそのまま引き継げます(プラットフォームに依存しないコード)
  • Windows 固有 APIには、Windows 以外のターゲット向けのクロスプラットフォームな代替手段が必要です
主な検討事項
  • プラットフォーム固有のコードで Windows.* API を使用している場合、Windows 以外のターゲット向けに条件付きコンパイルまたは抽象化が必要です
  • WinRT API(センサー、地理位置情報、メディアキャプチャ)には、Uno の実装またはプラットフォーム固有の代替手段が必要です
  • MSIX パッケージ化は Windows のみで利用できます。その他のプラットフォームでは、ネイティブの配布方法を使用します

Uno Platform の開発パターンについては、[skill:dotnet-uno-platform] を参照してください。ターゲットごとのデプロイについては、[skill:dotnet-uno-targets] を参照してください。


判断マトリックス

どの移行経路を選ぶかを決める際に、このマトリックスを使用してください。適切な選択肢は具体的な制約によって異なり、すべてに当てはまる「最善」の移行先はありません。

主な目標別
目標推奨される移行経路代替案
リスクを最小限に抑え、迅速に移行するWPF/WinForms から .NET 8+ へ--
モダンな Windows UIWPF から WinUI 3 へFluent テーマを使用した WPF .NET 9+
Windows アプリからクロスプラットフォームへWPF から Uno Platform へ重要な部分を Blazor で書き換える
UWP からクロスプラットフォームへUWP から Uno Platform へUWP から WinUI 3 へ(Windows 専用のまま)
UWP のモダナイズ(Windows 専用)UWP から WinUI 3 へ.NET 9 プレビュー版で UWP を使用
レガシー WinForms のモダナイズWinForms から .NET 8+ へBlazor または WPF で段階的に書き換える
制約別
制約最適な移行経路理由
予算/時間が限られている.NET 8+ への移行(同じフレームワーク)労力が最小限で、同じコードベースを維持できます
Windows 専用である必要があるWinUI 3 または WPF .NET 8+モダンな UI には WinUI、変更を最小限にするには WPF
クロスプラットフォームにする必要があるUno PlatformWinUI XAML サーフェスを活用して、最も広範なプラットフォームに対応できます
既存の WPF コードベースが大規模まず WPF .NET 8+ へ移行し、その後に評価するUI を書き換える前に、最新のランタイムで安定させます
既存の UWP コードベースがあるWinUI 3(Windows)または Uno(クロスプラットフォーム)既存のコードに最も近い API サーフェスです
チームにウェブ開発のスキルがあるBlazor(書き換え)ウェブ開発の専門知識をデスクトップ/モバイルで活用できます
段階的な移行戦略

大規模なアプリケーションでは、段階的なアプローチによってリスクを軽減できます。

  1. ステージ 1:ランタイムの移行 -- .NET Framework から .NET 8+ へ移行します(UI フレームワークはそのまま)。互換性を検証し、パフォーマンスを向上させ、最新の NuGet パッケージを利用できるようにします。
  2. ステージ 2:パターンのモダナイズ -- Host ビルダー、DI、MVVM Toolkit、モダンな C# を採用します。[skill:dotnet-wpf-modern] または [skill:dotnet-winforms-basics] を参照してください。
  3. ステージ 3:UI の移行(必要な場合)-- 要件に応じて WinUI 3、Uno Platform、または Blazor に移行します。ステージ 1 と 2 が安定している場合にのみ進めてください。

このアプローチにより、「一度にすべてを書き換える」リスクを回避し、各段階で段階的な価値を提供できます。


エージェントが陥りやすい注意点

  1. 制約を理解せずに、単一の移行先を「正しい選択肢」として推奨しないでください。 常にトレードオフを示し、複数の選択肢を提示してください。予算、スケジュール、チームの専門知識、プラットフォーム要件はすべて、判断に影響します。
  2. UI フレームワークの変更を提案する前に、.NET 8+ ランタイムへの移行を省略しないでください。 .NET Framework から .NET 8+ への移行(UI フレームワークはそのまま)をステージ 1 としてください。.NET Framework から WPF を WinUI に移行するほうが、.NET 8+ から移行するよりも大幅に困難です。
  3. WPF が「レガシー」で、移行が必須だと決めつけないでください。 .NET 8+ 上の WPF は、新機能(.NET 9+ の Fluent テーマやパフォーマンスの向上など)を伴って積極的にメンテナンスされています。多くのアプリケーションは、WPF を使い続けることで十分に役立ちます。
  4. dotnet-upgrade-assistant を使う前に、必ず analyze を実行してください。 アップグレードの前に必ず分析し、変更範囲と潜在的な問題を把握してください。
  5. WPF の XAML と WinUI の XAML を混同しないでください。 概念は似ていますが、API の範囲は異なります(Window、DataContext と x:Bind、NavigationView のパターンなど)。移行には、名前空間の変更以上の作業が必要です。
  6. UWP から WinUI 3 への移行には、名前空間の更新だけでなく、アプリモデルの変更も伴うことを忘れないでください。 Window.Current、CoreDispatcher、CoreApplication の API はすべて、異なるパターンに置き換えられます。
  7. Windows 専用のシンプルなアプリに Uno Platform を推奨しないでください。 アプリケーションにクロスプラットフォーム対応が不要なら、WinUI 3 または WPF .NET 8+ のほうがシンプルで、メンテナンスの負担も少なくなります。

参考資料

コメント