.NETでの winapp CLI の使用

このガイドは、ほとんどの.NETプロジェクトの種類で機能する必要があります。 この手順は、コンソールと UI ベースのプロジェクト (WPF など) の両方でテストされています。 実際の例については、samples フォルダーの dotnet-app (コンソール) サンプルと wpf-app (WPF) サンプルを確認してください。

このガイドでは、winapp CLI と .NET アプリケーションを使用して、パッケージ ID を使用してデバッグし、アプリケーションを MSIX としてパッケージ化する方法について説明します。

パッケージ ID は、Windows app モデルの主要な概念です。 これにより、アプリケーションは特定のWindows API (通知、セキュリティ、AI API など) にアクセスでき、クリーンなインストール/アンインストール エクスペリエンスが提供されます。

標準の実行可能ファイル ( dotnet build で作成されたものなど) にはパッケージ ID がありません。 このガイドでは、デバッグ用に追加し、配布用にパッケージ化する方法を示します。

[前提条件]

  1. .NET SDK: .NET SDK をインストールします (インストール後に再起動する必要があります)。

    winget install Microsoft.DotNet.SDK.10 --source winget
    
  2. winapp CLI: winget を使用して winapp ツールをインストールします (既にインストールされている場合は更新します)。

    winget install Microsoft.winappcli --source winget
    

1. 新しい.NET アプリを作成する

まず、単純な.NETコンソール アプリケーションを作成します。

dotnet new console -n dotnet-app
cd dotnet-app

これを実行して、すべてが動作していることを確認します。

dotnet run

出力は "Hello, World!" にする必要があります。

2. コードを更新して ID を確認する

アプリがパッケージ ID で実行されているかどうかを確認するように更新します。 Windows ランタイム API を使用してパッケージ API にアクセスします。

最初に、特定の Windows SDK バージョンを対象として、project ファイルを更新します。 dotnet-app.csproj を開き、Windows SDK バージョンを含むように TargetFramework を変更します。

  <TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>

これにより、追加のパッケージを必要とせずにWindows ランタイム API にアクセスできます。

次に、 Program.cs の内容を次のコードに置き換えます。 このコードは、Windows ランタイム API を使用して現在のパッケージ ID の取得を試みます。 成功した場合は、パッケージ ファミリ名が出力されます。それ以外の場合は、"パッケージ化されていません" が出力されます。

using Windows.ApplicationModel;

try
{
    var package = Package.Current;
    var familyName = package.Id.FamilyName;
    Console.WriteLine($"Package Family Name: {familyName}");
}
catch (InvalidOperationException)
{
    // Thrown when app doesn't have package identity
    Console.WriteLine("Not packaged");
}

3. ID なしで実行する

次に、通常どおりにアプリを実行します。

dotnet run

"パッケージ化されていません" という出力が表示されます。 これにより、標準の実行可能ファイルがパッケージ ID なしで実行されていることが確認されます。

4. winapp CLI を使用してProjectを初期化する

winapp init コマンドは、.csproj ファイルを自動的に検出し、.NET固有のセットアップを実行します。 一度に必要なものがすべて設定されます。 TargetFrameworkの検証、必要な NuGet パッケージの追加、アプリ マニフェストの生成、アセットの生成を行います。

次のコマンドを実行し、プロンプトに従います。

winapp init

プロンプトが表示されたら、次を実行します。

  • パッケージ名: Enter キーを押して既定値を受け入れる (dotnet-app)
  • Publisher名: Enter キーを押して既定値をそのまま使用するか、名前を入力します
  • バージョン: Enter キーを押して 1.0.0.0 を受け入れる
  • Description: Enter キーを押して既定値 (Windows アプリケーション) をそのまま使用するか、説明を入力します
  • Windows アプリ SDKセットアップ: [安定版]、[プレビュー]、または [試験段階] を選択します (追加するWindows アプリ SDKバージョンを決定します)
  • TargetFramework update: TargetFrameworkにサポートされているWindows SDK バージョンが含まれていない場合は、更新するように求められます (例: net10.0-windows10.0.26100.0)
  • 開発者モード: "開発者モード" についてメッセージが表示された場合は、必要に応じて有効にすることができますが、管理者特権が必要であることに注意してください

このコマンドは次の操作を行います:

  • TargetFramework の.csprojを、サポートされている Windows TFM に更新します (必要な場合)
  • Microsoft.WindowsAppSDK、Microsoft.Windows.SDK.BuildTools、および Microsoft.Windows.SDK.BuildTools.WinApp NuGet パッケージ参照を .csproj に追加します
  • アプリ ID の Package.appxmanifest フォルダーと Assets フォルダーを作成する

注

ネイティブ/C++ プロジェクトとは異なり、.NET フローは notwinapp.yaml ファイルを作成します。 NuGet パッケージは、 .csprojを介して直接管理されます。 複製後、 winapp restore または dotnet restoreを実行します。

Package.appxmanifestを開いて、表示名、発行元、機能などのプロパティをさらにカスタマイズできます。

パッケージがプロジェクトに追加されたことを確認するには:

dotnet list package

出力に Microsoft.WindowsAppSDK と Microsoft.Windows.SDK.BuildTools が表示されます。

コンソール出力(何もすることがない)

コンソール アプリを構築しているため、コンソール出力は現在のターミナルに留まる必要があります。 AUMID ライセンス認証では、パッケージ化されたアプリにコンソールが提供されないため、コンソール アプリは正しく実行され、何も出力されません。

winapp はこれを自動的に処理します。代わりに、 OutputType=Exe を持つアプリが実行エイリアスを介して起動され、ターミナルの stdin/stdout/stderr が継承されます。 ステージするマニフェストに必要な uap5:ExecutionAlias が追加されるため、構成する必要はありません。

UI アプリ (WPF、WinForms、WinUI) は独自のウィンドウをレンダリングするため、AUMID のアクティブ化は維持されます。

とにかくコンソール アプリに対して AUMID を強制するには、dotnet-app.csproj内の任意の<PropertyGroup>内で次を設定します。その後、アプリはコンソールなしで実行され、ターミナルに何も出力されません。

<WinAppRunUseExecutionAlias>false</WinAppRunUseExecutionAlias>

コマンド名を自分で選択する場合は、 winapp manifest add-alias を実行して Package.appxmanifestで宣言します。作成したエイリアスは as-is使用されます。

5. ID を使用したデバッグ

winapp init Microsoft.Windows.SDK.BuildTools.WinApp NuGet パッケージをプロジェクトに追加したので、次のコマンドを実行するだけです。

dotnet run

これにより、内部で winapp run が自動的に呼び出されます。ルーズ レイアウト パッケージの作成、Windowsへの登録、完全なパッケージ ID でアプリの起動を行います。

dotnet run後に記述する引数は、プロジェクトがこのパッケージを参照していない場合とまったく同じように、アプリケーションに移動します。

dotnet run --devtools          # your app receives --devtools
dotnet run -- --devtools       # identical: the SDK consumes the -- before forwarding

アプリのフラグが --configuration オプション(--framework、--project、-c、-f、-r、--、...)でもある場合は、dotnet run を使用します。これがないと、SDK がトークンを取得してしまい、アプリでは受け取れません。

dotnet run -- --configuration Release   # your app receives --configuration Release

WinAppRun* MSBuild プロパティを使用して WinApp ランチャー自体を構成します。 MSBuild はこれらを使用するため、アプリケーションに到達することはありません。

dotnet run -p:WinAppRunDebugOutput=true --devtools

ここでは、 --devtools がアプリに渡されている間、プロパティによって WinApp が構成されます。 組み合わせることができないプロパティを含む、プロパティの完全な一覧については、dotnet runサポートを参照してください。

注

パッケージ ソースに関する NuGet の脆弱性の警告 (NU1900) が表示される場合があります。 これらは無視しても安全です。ビルドには影響しません。

次のような出力が表示されます。

Package Family Name: dotnet-app_12345abcde

これにより、アプリが有効なパッケージ ID で実行されていることを確認できます。

代替手段: 手動 winapp run

winapp initを使用していない (または NuGet パッケージを削除した) 場合は、手動でビルドして実行できます。 winapp run はプロジェクトを直接受け入れます (プロジェクト モード) — .csproj をビルドして起動するため、ビルド出力フォルダーをポイントしたり、個別にビルドしたりする必要はありません。

# Build and run the project in one step (project mode)
winapp run .

# ...or run a specific project / configuration / architecture
winapp run .\dotnet-app.csproj -c Debug --arch x64

プロジェクトのネイティブ AOT 構成を実行するには、 プロジェクトで AOT を有効に して、次を実行します。

winapp run . --aot
winapp run . --aot -c Release

x64 または ARM64 を使用します。 1 回限りのオーバーライドの場合は、 -p PublishAot=trueを追加します。

必要に応じて、事前にビルドされた出力フォルダーで winapp run をポイントすることもできます (フォルダー モード)。

dotnet build -c Debug
winapp run .\bin\Debug\net10.0-windows10.0.26100.0

Project モードでは、パッケージ化された WinUI アプリとパッケージ化されていない WinUI アプリの両方がサポートされます。projectのWindowsPackageTypeからどれが検出され、対応するアーキテクチャWindows アプリランタイムが自動的にインストールされます。 パッケージ化されていないプロジェクトを強制的に実行するには、 -p WindowsPackageType=Noneを追加します。

マルチプロジェクト アプリ (クラス ライブラリを参照するアプリ) は正しくビルドされます。winapp は、グラフ全体でアプリのアーキテクチャを強制するのではなく、互換性のあるプラットフォーム上で AnyCPU/netstandard2.0 参照を保持します。 RID のみは既定値のままです。有効な構成で自己完結型プロファイル (トリミングされたリリース ビルドなど) が必要な場合、winapp は参照先ライブラリのプラットフォームを変更せずに一致するプロファイルを選択します。

dotnet build の出力はリアルタイムで表示され、まず正確な呼び出し内容が表示されます。 winapp 独自のビルド決定トレース用に --verbose を追加します。 .NET SDK 8.0.100 以降が必要です。 完全なオプションの一覧については、使用状況リファレンスのwinapp runを参照してください。

Windows SDK はインストールされていませんか? C#/WinRT オーサリング プロジェクトでは、通常、ビルドに登録済みの Windows SDK が必要です。 プロジェクト モードで何も検出されない場合(クリーンな CI、コンテナー、SDK のない開発マシンなど)、自動復元された Microsoft.Windows.SDK.NET.Ref パッケージ内の winmds を cswinrt に参照させるため、ビルドは引き続き成功します。対応は不要です。 SDK がインストールされている場合、または自分で -p CsWinRTWindowsMetadata=… 設定した場合は、何も行われません。

NuGet パッケージを再度追加するには: dotnet add package Microsoft.Windows.SDK.BuildTools.WinApp --prerelease

ヒント

自動dotnet run統合を無効にするには、<EnableWinAppRunSupport>false</EnableWinAppRunSupport>に.csprojを追加します。 カスタマイズ オプションについては 、dotnet 実行のサポート ドキュメント を参照してください。

代替手段: Sparse パッケージ ID

特にスパース パッケージの動作 (ファイルをコピーしない ID) が必要な場合は、代わりに create-debug-identity を使用できます。 これにより、独立したレイアウトを作成するのではなく、実行ファイルを指す sparse パッケージが登録されます:

winapp create-debug-identity .\bin\Debug\net10.0-windows10.0.26100.0\dotnet-app.exe

その後、実行可能ファイルを直接実行します (ファイルを再構築または上書きする可能性があるため、 dotnet run は使用しないでください)。

.\bin\Debug\net10.0-windows10.0.26100.0\dotnet-app.exe

代替手段: 手動 MSBuild ターゲット

NuGet パッケージを使用しない場合は、デバッグ ビルド後に create-debug-identity 実行されるカスタム MSBuild ターゲットを追加できます。 .csproj ファイルの最後、終了</Project> タグの直前にこれを追加します。

  <!-- Automatically apply debug identity after Debug builds -->
  <Target Name="ApplyDebugIdentity" AfterTargets="Build" Condition="'$(Configuration)' == 'Debug'">
    <Exec Command="winapp create-debug-identity &quot;$(TargetDir)$(TargetName).exe&quot;" 
          WorkingDirectory="$(ProjectDir)" 
          IgnoreExitCode="false" />
  </Target>

この構成では、 dotnet build はデバッグ ID を適用し、実行可能ファイルを直接実行できます。 dotnet runは ID を再構築して上書きする可能性があるので、ビルド後に exe を手動で実行してください。

ヒント

高度なデバッグ ワークフロー (デバッガーのアタッチ、IDE セットアップ、スタートアップ デバッグ) については、 デバッグ ガイドを参照してください。

これをスキップする場合: ID が適用されるタイミングを明示的に制御する場合、または開発サイクルの大部分で ID を必要としないコードに取り組んでいる場合は、上記の手動アプローチの方が簡単な場合があります。

6. Windows アプリ SDKの使用 (省略可能)

Windows アプリ SDKを使用すると、通知システム、ウィンドウ API、アプリライフサイクル管理、デバイス上の AI など、Windows SDK の基本機能を超えた最新のWindows API にアクセスできます。 アプリでこれらの機能のいずれかが必要な場合は、この手順が適しています。 配布にパッケージ ID が必要な場合は、手順 7 に進むことができます。

winapp init (手順 4) を実行した場合、Microsoft.WindowsAppSDKは、.csproj への NuGet パッケージ参照として既に追加されています。 dotnet list packageで確認できます。 init 中に SDK のセットアップをスキップした場合、または手動で追加する必要がある場合は、次を実行します。

dotnet add package Microsoft.WindowsAppSDK

Program.cs を更新する

Program.cs の内容全体を次のコードに置き換えます。このコードにより、Windows アプリ ランタイムのバージョン チェックが追加されます。

using Windows.ApplicationModel;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var package = Package.Current;
            var familyName = package.Id.FamilyName;
            Console.WriteLine($"Package Family Name: {familyName}");
            
            // Get Windows App Runtime version using the API
            var runtimeVersion = Microsoft.Windows.ApplicationModel.WindowsAppRuntime.RuntimeInfo.AsString;
            Console.WriteLine($"Windows App Runtime Version: {runtimeVersion}");
        }
        catch (InvalidOperationException)
        {
            // Thrown when app doesn't have package identity
            Console.WriteLine("Not packaged");
        }
    }
}

ビルドと実行

Windows アプリ SDKを使用してアプリケーションをリビルドして実行します。 WinAppSDK を追加したため、Identity への再登録が必要となり、winapp がランタイム依存関係を追加します。 WinApp NuGet パッケージを追加した場合 (推奨)、 dotnet runを実行するだけです。 それ以外の場合 ( dotnet-app をプロジェクト名に置き換えます)。

dotnet build -c Debug
winapp run .\bin\Debug\net10.0-windows10.0.26100.0

次のような出力が表示されます。

Package Family Name: dotnet-app.debug_12345abcde
Windows App Runtime Version: 8000.770.947.0

Windows アプリ SDK NuGet パッケージには、最新のWindows API にアクセスするために必要なすべてのアセンブリが含まれています。

  • 通知とライブ タイル
  • ウィンドウとアプリのライフサイクル
  • プッシュ通知
  • さらに多くのWindows アプリ SDKコンポーネント

Windows アプリ SDKの詳細については、Windows アプリ SDKドキュメントを参照してください。

7. MSIX を使用したパッケージ化

アプリを配布する準備ができたら、同じマニフェストを使用して MSIX としてパッケージ化できます。

リリース用のビルド

まず、最適なパフォーマンスを得るためのリリース モードでアプリケーションをビルドします。

dotnet build -c Release

注

NuGet の脆弱性の警告 (NU1900) が表示される場合があります。 これらは無視しても安全であり、ビルド出力には影響しません。

開発証明書を生成する

パッケージ化する前に、署名用の開発証明書が必要です。 まだ生成していない場合は生成します。

winapp cert generate --if-exists skip

署名とパッケージ

パッケージ化と署名ができるようになりました。 pack コマンドをビルド出力フォルダーにポイントします ( dotnet-app と TFM パスをプロジェクトの値に置き換えます)。

# package and sign the app with the generated certificate
winapp pack .\bin\Release\net10.0-windows10.0.26100.0 --manifest .\Package.appxmanifest --cert .\devcert.pfx 

注: pack コマンドは、現在のディレクトリから Package.appxmanifest を自動的に使用し、パッケージ化する前にターゲット フォルダーにコピーします。 生成された .msix ファイルは現在のディレクトリにあります。

ヒント: ビルド出力フォルダーの検索をスキップし、プロジェクトから直接パックすることもできます。 winapp package .\dotnet-app.csproj --cert .\devcert.pfx プロジェクトを発行し、その出力を 1 つのステップでパッケージ化します (プロジェクト モードは既定でリリース構成になります)。 Project モードでは、ビルド オプション-c、--arch、-f、--no-build、--no-restore、-pを受け取り、再構築せずに既存のビルドをパッケージ化する--no-buildを追加できます。

証明書をインストールする

MSIX パッケージをインストールする前に、開発証明書をインストールする必要があります。 管理者として次のコマンドを実行します。

winapp cert install .\devcert.pfx

インストールと実行

生成された *.msix ファイルをダブルクリックして、パッケージをインストールします。

次のように入力して、ターミナル内の任意の場所からアプリを実行できるようになりました。

dotnet-app

"パッケージ ファミリ名" の出力が表示され、インストールされ、ID で実行されていることを確認します。

ヒント

(コード変更後など) アプリを再パッケージ化する必要がある場合は、Versionをもう一度実行する前に、Package.appxmanifestのwinapp packをインクリメントします。 Windowsインストールされているパッケージを更新するには、より高いバージョン番号が必要です。

ヒント

  1. 配布の準備ができたら、証明機関のコード署名証明書を使用して MSIX に署名し、ユーザーが自己署名証明書をインストールする必要がないようにすることができます。
  2. Microsoft Storeは MSIX に署名します。送信前に署名する必要はありません。
  3. サポートするアーキテクチャ (x64、Arm64) ごとに 1 つずつ、複数の MSIX パッケージを作成する必要がある場合があります。 特定のアーキテクチャ (-r または dotnet build) を対象にするには、dotnet build -c Release -r win-x64で dotnet build -c Release -r win-arm64 フラグを使用します。

MSIX パッケージの自動化 (省略可能)

リリース ビルドの一部として MSIX パッケージ化を自動化するには、このターゲットを .csproj ファイルに追加します (デバッグ ID ターゲットと共に追加できます)。

  <!-- Automatically package as MSIX after Release builds -->
  <Target Name="PackageMsix" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
    <!-- Package and sign directly from build output -->
    <Exec Command="winapp pack &quot;$(TargetDir.TrimEnd('\'))&quot; --cert &quot;$(ProjectDir)devcert.pfx&quot;" 
          WorkingDirectory="$(ProjectDir)" 
          IgnoreExitCode="false" />
  </Target>

この構成では、次の操作を行います。

  • リリース モード (dotnet build -c Release) でビルドすると、MSIX パッケージが自動的に作成されます
  • MSIX はパッケージ化され、開発証明書で署名されます
  • 最終的な .msix ファイルはプロジェクトのルートにあります

条件をPackagedReleaseに変更することで、カスタム構成 ('$(Configuration)' == 'PackagedRelease' など) を作成することもできます。

次のステップ

  • winget を使用して配布: MSIX を Windows パッケージ マネージャー Community Repository に送信します
  • Microsoft Store に発行する: を使用してパッケージを送信する
  • CI/CD の設定: setup-WinAppCli GitHub Action を使用して、パイプライン内のパッケージングを自動化します
  • Explore Windows API: パッケージ ID を使用して、 これで、Notifications、on-device AI、およびその他の identity 依存 API