mcpField
W
winui3-migration-guide

winui3-migration-guide

github.com/github開発40.5k5.7k 回インストール1 日前に更新
リポジトリ

winui3-migration-guide について

winui3-migration-guideは、UWPアプリをWinUI 3へ移行する開発者や、生成コードのAPIを確認する開発者向けのスキルです。UI、ウィンドウ、スレッド、テストの対応表や修正例、チェックリストを提供します。

主な機能

  1. 01UWPの名前空間とAPIをWinUI 3に対応付け
  2. 02ダイアログとディスパッチャーの一般的な修正
  3. 03ウィンドウ、ピッカー、スレッド処理の更新
  4. 04バックグラウンドタスクと設定の移行案内
  5. 05プロジェクトとテスト変更のチェックリスト

活用シーン

  1. 01UWPアプリのWinUI 3への移行
  2. 02生成コードに残る旧UWP APIの確認
  3. 03ウィンドウとファイルピッカーの置き換え
  4. 04WinUI 3向けテストの更新

インストール

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

$npx skills add https://github.com/github/awesome-copilot --skill winui3-migration-guide

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

詳細

WinUI 3 移行ガイド

UWP アプリを WinUI 3/Windows App SDK に移行する場合や、生成されたコードがレガシーな UWP パターンではなく、正しい WinUI 3 API を使用しているか確認する場合に、このスキルを使用します。


名前空間の変更

すべての Windows.UI.Xaml.* 名前空間は Microsoft.UI.Xaml.* に移行します。

UWP 名前空間WinUI 3 名前空間
Windows.UI.XamlMicrosoft.UI.Xaml
Windows.UI.Xaml.ControlsMicrosoft.UI.Xaml.Controls
Windows.UI.Xaml.MediaMicrosoft.UI.Xaml.Media
Windows.UI.Xaml.InputMicrosoft.UI.Xaml.Input
Windows.UI.Xaml.DataMicrosoft.UI.Xaml.Data
Windows.UI.Xaml.NavigationMicrosoft.UI.Xaml.Navigation
Windows.UI.Xaml.ShapesMicrosoft.UI.Xaml.Shapes
Windows.UI.CompositionMicrosoft.UI.Composition
Windows.UI.InputMicrosoft.UI.Input
Windows.UI.ColorsMicrosoft.UI.Colors
Windows.UI.TextMicrosoft.UI.Text
Windows.UI.CoreMicrosoft.UI.Dispatching(ディスパッチャー用)

Copilot で最もよくあるミス 3 選

1. XamlRoot を指定しない ContentDialog
// ❌ WRONG — Throws InvalidOperationException in WinUI 3
var dialog = new ContentDialog
{
    Title = "Error",
    Content = "Something went wrong.",
    CloseButtonText = "OK"
};
await dialog.ShowAsync();
// ✅ CORRECT — Set XamlRoot before showing
var dialog = new ContentDialog
{
    Title = "Error",
    Content = "Something went wrong.",
    CloseButtonText = "OK",
    XamlRoot = this.Content.XamlRoot  // Required in WinUI 3
};
await dialog.ShowAsync();
2. ContentDialog ではなく MessageDialog を使用する
// ❌ WRONG — UWP API, not available in WinUI 3 desktop
var dialog = new Windows.UI.Popups.MessageDialog("Are you sure?", "Confirm");
await dialog.ShowAsync();
// ✅ CORRECT — Use ContentDialog
var dialog = new ContentDialog
{
    Title = "Confirm",
    Content = "Are you sure?",
    PrimaryButtonText = "Yes",
    CloseButtonText = "No",
    XamlRoot = this.Content.XamlRoot
};
var result = await dialog.ShowAsync();
if (result == ContentDialogResult.Primary)
{
    // User confirmed
}
3. DispatcherQueue ではなく CoreDispatcher を使用する
// ❌ WRONG — CoreDispatcher does not exist in WinUI 3
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
    StatusText.Text = "Done";
});
// ✅ CORRECT — Use DispatcherQueue
DispatcherQueue.TryEnqueue(() =>
{
    StatusText.Text = "Done";
});

// With priority:
DispatcherQueue.TryEnqueue(DispatcherQueuePriority.High, () =>
{
    ProgressBar.Value = 100;
});

ウィンドウ管理の移行

ウィンドウ参照
// ❌ WRONG — Window.Current does not exist in WinUI 3
var currentWindow = Window.Current;
// ✅ CORRECT — Use a static property in App
public partial class App : Application
{
    public static Window MainWindow { get; private set; }

    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        MainWindow = new MainWindow();
        MainWindow.Activate();
    }
}
// Access anywhere: App.MainWindow
ウィンドウ管理
UWP APIWinUI 3 API
ApplicationView.TryResizeView()AppWindow.Resize()
AppWindow.TryCreateAsync()AppWindow.Create()
AppWindow.TryShowAsync()AppWindow.Show()
AppWindow.TryConsolidateAsync()AppWindow.Destroy()
AppWindow.RequestMoveXxx()AppWindow.Move()
AppWindow.GetPlacement()AppWindow.Position プロパティ
AppWindow.RequestPresentation()AppWindow.SetPresenter()
タイトルバー
UWP APIWinUI 3 API
CoreApplicationViewTitleBarAppWindowTitleBar
CoreApplicationView.TitleBar.ExtendViewIntoTitleBarAppWindow.TitleBar.ExtendsContentIntoTitleBar

ダイアログとピッカーの移行

ファイル/フォルダーのピッカー
// ❌ WRONG — UWP style, no window handle
var picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".txt");
var file = await picker.PickSingleFileAsync();
// ✅ CORRECT — Initialize with window handle
var picker = new FileOpenPicker();
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
picker.FileTypeFilter.Add(".txt");
var file = await picker.PickSingleFileAsync();

スレッド処理の移行

UWP パターンWinUI 3 相当
CoreDispatcher.RunAsync(priority, callback)DispatcherQueue.TryEnqueue(priority, callback)
Dispatcher.HasThreadAccessDispatcherQueue.HasThreadAccess
CoreDispatcher.ProcessEvents()相当する API はありません — 非同期コードを再構成してください
CoreWindow.GetForCurrentThread()利用できません — DispatcherQueue.GetForCurrentThread() を使用してください

主な違い:UWP は ASTA(アプリケーション STA)を使用し、組み込みの再入防止機能を備えています。WinUI 3 はこの保護機能のない標準 STA を使用します。非同期コードがメッセージを処理する際は、再入の問題に注意してください。


バックグラウンドタスクの移行

// ❌ WRONG — UWP IBackgroundTask
public sealed class MyTask : IBackgroundTask
{
    public void Run(IBackgroundTaskInstance taskInstance) { }
}
// ✅ CORRECT — Windows App SDK AppLifecycle
using Microsoft.Windows.AppLifecycle;

// Register for activation
var args = AppInstance.GetCurrent().GetActivatedEventArgs();
if (args.Kind == ExtendedActivationKind.AppNotification)
{
    // Handle background activation
}

アプリ設定の移行

シナリオパッケージ化されたアプリパッケージ化されていないアプリ
シンプルな設定ApplicationData.Current.LocalSettingsLocalApplicationData 内の JSON ファイル
ローカルファイルストレージApplicationData.Current.LocalFolderEnvironment.GetFolderPath(SpecialFolder.LocalApplicationData)

GetForCurrentView() の置き換え

GetForCurrentView() を使用するすべてのパターンは、WinUI 3 デスクトップアプリでは利用できません。

UWP APIWinUI 3 での置き換え
UIViewSettings.GetForCurrentView()AppWindow のプロパティを使用
ApplicationView.GetForCurrentView()AppWindow.GetFromWindowId(windowId)
DisplayInformation.GetForCurrentView()Win32 の GetDpiForWindow() または XamlRoot.RasterizationScale
CoreApplication.GetCurrentView()利用できません — ウィンドウを手動で追跡してください
SystemNavigationManager.GetForCurrentView()NavigationView で戻るナビゲーションを直接処理してください

テストの移行

UWP 単体テストプロジェクトは WinUI 3 では動作しません。WinUI 3 テストプロジェクトテンプレートへ移行する必要があります。

UWPWinUI 3
単体テストアプリ (Universal Windows)単体テストアプリ (WinUI in Desktop)
UWP 型を含む標準の MSTest プロジェクトXaml ランタイムには WinUI テストアプリを使用する必要があります
すべてのテストに [TestMethod]ロジックには [TestMethod]、XAML/UI テストには [UITestMethod]
クラスライブラリ (Universal Windows)クラスライブラリ (WinUI in Desktop)
// ✅ WinUI 3 unit test — use [UITestMethod] for any XAML interaction
[UITestMethod]
public void TestMyControl()
{
    var control = new MyLibrary.MyUserControl();
    Assert.AreEqual(expected, control.MyProperty);
}

ポイント: [UITestMethod] 属性は、XAML UI スレッドでテストを実行するようテストランナーに指示します。これは、あらゆる Microsoft.UI.Xaml 型をインスタンス化するために必要です。


移行チェックリスト

  1. すべての Windows.UI.Xaml.* using ディレクティブを Microsoft.UI.Xaml.* に置き換える
  2. Windows.UI.Colors を Microsoft.UI.Colors に置き換える
  3. CoreDispatcher.RunAsync を DispatcherQueue.TryEnqueue に置き換える
  4. Window.Current を App.MainWindow 静的プロパティに置き換える
  5. すべての ContentDialog インスタンスに XamlRoot を追加する
  6. すべてのピッカーを InitializeWithWindow.Initialize(picker, hwnd) で初期化する
  7. MessageDialog を ContentDialog に置き換える
  8. ApplicationView/CoreWindow を AppWindow に置き換える
  9. CoreApplicationViewTitleBar を AppWindowTitleBar に置き換える
  10. すべての GetForCurrentView() 呼び出しを AppWindow の同等のものに置き換える
  11. Share および Print マネージャーの相互運用を更新する
  12. IBackgroundTask を AppLifecycle アクティベーションに置き換える
  13. プロジェクトファイルを更新する: TFM を net10.0-windows10.0.22621.0 にし、<UseWinUI>true</UseWinUI> を追加する
  14. 単体テストを 単体テストアプリ (WinUI in Desktop) プロジェクトへ移行する。XAML テストには [UITestMethod] を使用する
  15. パッケージ化構成と非パッケージ化構成の両方でテストする

コメント