このガイドでは、 winapp CLI と C++ アプリケーションを使用してパッケージ ID を使用してデバッグし、アプリケーションを MSIX としてパッケージ化する方法について説明します。
パッケージ ID は、Windows app モデルの主要な概念です。 これにより、アプリケーションは特定のWindows API (通知、セキュリティ、AI API など) にアクセスでき、クリーンなインストール/アンインストール エクスペリエンスが提供されます。
標準の実行可能ファイル ( cmake --build で作成されたものなど) にはパッケージ ID がありません。 このガイドでは、デバッグ用に追加し、配布用にパッケージ化する方法を示します。
[前提条件]
ビルド ツール: CMake でサポートされているコンパイラ ツールチェーンを使用します。 この例では、Visual Studioを使用します。 コミュニティ エディションは、次を使用してインストールできます (既にインストールされている場合は更新します)。
winget install --id Microsoft.VisualStudio.Community --source winget --override "--add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --passive --wait"インストール後に再起動します。
CMake: CMake をインストールする (または既にインストールされている場合は更新):
winget install Kitware.CMake --source wingetwinapp CLI: winget を使用して
winappcli をインストールします (既にインストールされている場合は更新します)。winget install Microsoft.winappcli --source winget
1. 新しい C++ アプリを作成する
まず、単純な C++ アプリケーションを作成します。 projectの新しいディレクトリを作成します。
mkdir cpp-app
cd cpp-app
基本的な "Hello, world!" プログラムを使用して、 main.cpp ファイルを作成します。
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
ビルドを構成する CMakeLists.txt ファイルを作成します。
cmake_minimum_required(VERSION 3.20)
project(cpp-app)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(cpp-app main.cpp)
ビルドして実行して、すべてが動作していることを確認します。
cmake -B build
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
出力は "Hello, world!" にする必要があります。
2. コードを更新して ID を確認する
アプリがパッケージ ID で実行されているかどうかを確認するように更新します。 これは、後の手順で ID が正しく動作していることを確認するのに役立ちます。 Windows ランタイム C++ API を使用してパッケージ API にアクセスします。
まず、CMakeLists.txt の末尾に次の行を追加して、Windows アプリ モデル ライブラリにリンクします。
# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
次に、 main.cpp の内容全体を次のコードに置き換えます。 このコードは、Windows ランタイム API を使用して現在のパッケージ ID の取得を試みます。 成功した場合は、パッケージ ファミリ名が出力されます。それ以外の場合は、"パッケージ化されていません" が出力されます。
#include <iostream>
#include <windows.h>
#include <appmodel.h>
int main() {
UINT32 length = 0;
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
if (result == ERROR_INSUFFICIENT_BUFFER) {
// We have a package identity
std::wstring familyName;
familyName.resize(length);
result = GetCurrentPackageFamilyName(&length, familyName.data());
if (result == ERROR_SUCCESS) {
std::wcout << L"Package Family Name: " << familyName.c_str() << std::endl;
} else {
std::wcout << L"Error retrieving Package Family Name" << std::endl;
}
} else {
// No package identity
std::cout << "Not packaged" << std::endl;
}
return 0;
}
3. ID なしで実行する
ここで、通常どおりアプリをリビルドして実行します。
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
"パッケージ化されていません" という出力が表示されます。 これにより、標準の実行可能ファイルがパッケージ ID なしで実行されていることが確認されます。
4. winapp CLI を使用してProjectを初期化する
winapp init コマンドは、アプリ マニフェスト、アセット、および必要に応じて C++ 開発用のWindows アプリ SDKヘッダーなど、必要なものをすべて一度に設定します。
次のコマンドを実行し、プロンプトに従います。
winapp init .
プロンプトが表示されたら、次を実行します。
- パッケージ名: Enter キーを押して既定値をそのまま使用します (cpp-app)
- Publisher名: Enter キーを押して既定値をそのまま使用するか、名前を入力します
- バージョン: Enter キーを押して 1.0.0.0 を受け入れる
- エントリポイント: Enterキーを押してデフォルト (cpp-app.exe) を受け入れます。
- Setup SDK: Windows アプリ SDKをダウンロードして C++ ヘッダーを生成するには、"Stable SDK" を選択します
このコマンドは次の操作を行います:
-
Package.appxmanifestの作成 - アプリの ID を定義するマニフェスト -
Assetsフォルダーの作成 - MSIX パッケージ化とストアの申請に必要なアイコン - Windows アプリ SDK ヘッダーとライブラリを含む
.winappフォルダーを作成する - SDK バージョンをピン留めするための
winapp.yaml構成ファイルを作成する
Package.appxmanifestを開いて、表示名、発行元、機能などのプロパティをさらにカスタマイズできます。
実行エイリアスの追加 (コンソール アプリの場合)
実行エイリアスを使用すると、ユーザーは任意のターミナル ( cpp-app など) から名前でアプリを実行できます。 また、開発中に winapp run --with-alias を有効にして、新しいウィンドウを開くのではなく、コンソール出力を現在のターミナルに保持します。
1 つを自動的に追加できます。
winapp manifest add-alias
または手動で: Package.appxmanifestを開き、uap5 タグがない場合は<Package>名前空間を追加し、<Applications><Application><Extensions>...内に拡張機能を追加します。
<Package
...
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
+ xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop6 uap10">
...
<Applications>
<Application ...>
...
+ <Extensions>
+ <uap5:Extension Category="windows.appExecutionAlias">
+ <uap5:AppExecutionAlias>
+ <uap5:ExecutionAlias Alias="cpp-app.exe" />
+ </uap5:AppExecutionAlias>
+ </uap5:Extension>
+ </Extensions>
</Application>
</Applications>
</Package>
5. ID を使用したデバッグ
アプリを完全にパッケージ化せずに ID (通知など) を必要とする機能をテストするには、 winapp runを使用できます。 これにより、ルーズ レイアウト パッケージ (実際の MSIX インストールと同様) が登録され、1 つの手順でアプリが起動されます。 デバッグに証明書や署名は必要ありません。
実行可能ファイルをビルドします。
cmake --build build --config DebugID を使用して実行する:
winapp run .\build\Debug --with-alias
--with-alias フラグは、実行エイリアスを使用してアプリを起動し、コンソール出力が現在のターミナルに留まります。 これには、手順 4 で追加した uap5:ExecutionAlias が必要です。
ヒント
winapp run は、パッケージをシステムに登録します。 このため、手順 8 で後でインストールしようとすると、MSIX が "既にインストール済み" と表示されることがあります。 完了したら、 winapp unregister を使用して開発パッケージをクリーンアップします。
次のような出力が表示されます。
Package Family Name: cpp-app_12345abcde
これにより、アプリが有効なパッケージ ID で実行されていることを確認できます。
代替手段: スパース パッケージ ID
特にスパース パッケージの動作 (ファイルをコピーしない ID) が必要な場合は、代わりに create-debug-identity を使用できます。
winapp create-debug-identity .\build\Debug\cpp-app.exe
.\build\Debug\cpp-app.exe
ヒント
高度なデバッグ ワークフロー (デバッガーのアタッチ、IDE セットアップ、スタートアップ デバッグ) については、 デバッグ ガイドを参照してください。
6. Windows アプリ SDKの使用 (省略可能)
winapp init中に SDK をセットアップすることを選択した場合は、.winapp/include フォルダー内のWindows アプリ SDKヘッダーにアクセスできるようになりました。 これにより、通知、ウィンドウ化、デバイス上の AI などの最新のWindows API にアクセスできます。 配布にパッケージ ID が必要な場合は、手順 7 に進むことができます。
Windows アプリ ランタイム バージョンを出力する簡単な例を追加しましょう。
CMakeLists.txt の更新
Windows アプリ SDK ヘッダーを含めるには、CMakeLists.txt の末尾に次の行を追加します。
# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
main.cppの更新
Windows アプリ ランタイム API を使用するには、main.cpp の内容全体を置き換えます。
#include <iostream>
#include <windows.h>
#include <appmodel.h>
#include <winrt/Microsoft.Windows.ApplicationModel.WindowsAppRuntime.h>
int main() {
// Initialize WinRT
winrt::init_apartment();
UINT32 length = 0;
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
if (result == ERROR_INSUFFICIENT_BUFFER) {
// We have a package identity
std::wstring familyName;
familyName.resize(length);
result = GetCurrentPackageFamilyName(&length, familyName.data());
if (result == ERROR_SUCCESS) {
std::wcout << L"Package Family Name: " << familyName.c_str() << std::endl;
// Get Windows App Runtime version using the API
auto runtimeVersion = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::RuntimeInfo::AsString();
std::wcout << L"Windows App Runtime Version: " << runtimeVersion.c_str() << std::endl;
} else {
std::wcout << L"Error retrieving Package Family Name" << std::endl;
}
} else {
std::cout << "Not packaged" << std::endl;
}
return 0;
}
ビルドと実行
Windows アプリ SDK ヘッダーを使用してアプリケーションをリビルドします。
cmake --build build --config Debug
winapp run .\build\Debug --with-alias
次のような出力が表示されます。
Package Family Name: cpp-app_12345abcde
Windows App Runtime Version: 1.8-stable (1.8.0)
.winapp/include ディレクトリには、次のようなWindows アプリ SDKに必要なすべてのヘッダーが含まれています。
-
winrt/- Windows ランタイム API にアクセスするための WinRT C++ プロジェクション ヘッダー -
Microsoft.UI.*.h- 最新の UI コンポーネント用の WinUI 3 ヘッダー -
MddBootstrap.h- Windows アプリ SDK のブートストラッピング -
WindowsAppSDK-VersionInfo.h- バージョン情報 - さらに多くのWindows アプリ SDKコンポーネント
Windows アプリ SDKの詳細については、Windows アプリ SDKドキュメントを参照してください。
7. 必要に応じヘッダーを復元する
.winapp フォルダーは.gitignoreによってwinapp initに自動的に追加されるため、ソース管理にはチェックインされません。 他のユーザーがプロジェクトを複製するときは、ビルドする前にこれらのファイルを復元する必要があります。
手動セットアップ
リポジトリを複製した後、次の 2 つのコマンドを実行します。
# Restore Windows App SDK headers
winapp restore
# Generate development certificate (optional - only if planning to package the app and sideload)
winapp cert generate --if-exists skip
その後、 cmake -B build と cmake --build build --config Debugを使用して通常どおりにビルドして実行できます。
CMake を使用した自動セットアップ
または、 CMakeLists.txtにセットアップ ロジックを追加して、これを自動化することもできます。 自動化、適切なリンク、最小限の C++20 標準を備えた完全な CMakeLists.txt を次に示します。
cmake_minimum_required(VERSION 3.20)
project(cpp-app)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Download winapp CLI if not available in PATH
find_program(WINAPP_CLI winapp)
if(NOT WINAPP_CLI)
set(WINAPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.winapp-tools")
set(WINAPP_CLI "${WINAPP_DIR}/winapp.exe")
if(NOT EXISTS "${WINAPP_CLI}")
message(STATUS "Downloading winapp CLI...")
# Determine architecture
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64")
set(WINAPP_ARCH "arm64")
else()
set(WINAPP_ARCH "x64")
endif()
# Download and extract
set(WINAPP_ZIP "${CMAKE_CURRENT_BINARY_DIR}/winappcli.zip")
file(DOWNLOAD
"https://github.com/microsoft/WinAppCli/releases/latest/download/winappcli-${WINAPP_ARCH}.zip"
"${WINAPP_ZIP}"
SHOW_PROGRESS
)
file(ARCHIVE_EXTRACT INPUT "${WINAPP_ZIP}" DESTINATION "${WINAPP_DIR}")
file(REMOVE "${WINAPP_ZIP}")
message(STATUS "winapp CLI downloaded to ${WINAPP_DIR}")
endif()
endif()
# Automatically restore Windows App SDK headers and generate certificate if needed
# This runs once during CMake configuration, not on every build
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include")
message(STATUS "Restoring Windows App SDK headers...")
execute_process(
COMMAND "${WINAPP_CLI}" restore
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE RESTORE_RESULT
)
if(NOT RESTORE_RESULT EQUAL 0)
message(WARNING "Failed to restore Windows App SDK. Run 'winapp restore' manually.")
endif()
endif()
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/devcert.pfx")
message(STATUS "Generating development certificate...")
execute_process(
COMMAND "${WINAPP_CLI}" cert generate --if-exists skip
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE CERT_RESULT
)
if(NOT CERT_RESULT EQUAL 0)
message(WARNING "Failed to generate certificate. Run 'winapp cert generate' manually.")
endif()
endif()
add_executable(cpp-app main.cpp)
# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
このセットアップでは、次の操作を行います。
- 誰かがリポジトリを複製して
cmake -B build実行すると、PATH に見つからない場合は winapp が自動的にダウンロードされます - Windows アプリ SDKヘッダーと証明書は自動的に復元されます
- ファイルが既に存在するかどうかを確認するため、コマンドは構成中に 1 回だけ実行されます (すべてのビルドでは実行されません)。
- コマンドが失敗した場合、手動で実行する手順を示す警告が CMake に表示されます
- ダウンロードした winapp は
.winapp-tools/に格納されます (必要に応じて、これを.gitignoreに追加します)
8. MSIX を使用したパッケージ
アプリを配布する準備ができたら、同じマニフェストを使用して MSIX としてパッケージ化できます。 MSIX では、クリーン インストール/アンインストール、自動更新、および信頼できるインストール エクスペリエンスが提供されます。
パッケージ ディレクトリを準備する
まず、最適なパフォーマンスを得るためのリリース モードでアプリケーションをビルドします。
cmake --build build --config Release
次に、配布に必要なファイルのみを含むディレクトリを作成し、リリース実行可能ファイルをコピーします。
mkdir dist
copy .\build\Release\cpp-app.exe .\dist\
開発証明書を生成する
MSIX パッケージに署名する必要があります。 ローカル テストの場合は、自己署名開発証明書を生成します。
winapp cert generate --if-exists skip
ヒント
証明書の発行者は、Package.appxmanifest 内の Publisher と一致する必要があります。
cert generate コマンドは、マニフェストからこれを自動的に読み取ります。
署名とパッケージ
これで、パッケージ化と署名を行うことができます。
# package and sign the app with the generated certificate
winapp pack .\dist --cert .\devcert.pfx
ヒント
pack コマンドは、現在のディレクトリから Package.appxmanifest を自動的に使用し、パッケージ化する前にターゲット フォルダーにコピーします。 生成された .msix ファイルは現在のディレクトリに格納されます。
証明書をインストールする
MSIX パッケージをインストールする前に、コンピューター上の開発証明書を信頼する必要があります。 このコマンドを管理者として実行します (証明書ごとに 1 回だけ実行する必要があります)。
winapp cert install .\devcert.pfx
インストールと実行
ヒント
手順 5 で winapp run を使用した場合は、パッケージがシステムに既に登録されている可能性があります。 最初 winapp unregister 使用して開発登録を削除してから、リリース パッケージをインストールします。
winapp pack コマンドを実行すると、プロジェクトのルート ディレクトリに MSIX ファイルが生成されます。 生成された .msix ファイルをダブルクリックするか、PowerShell を使用してパッケージをインストールします。
Add-AppxPackage .\cpp-app_1.0.0.0_x64.msix
ヒント
MSIX ファイル名には、バージョンとアーキテクチャ (例: cpp-app_1.0.0.0_arm64.msix) が含まれます。 ディレクトリで正確なファイル名を確認します。
次のように入力して、ターミナル内の任意の場所からアプリを実行できるようになりました。
cpp-app
"パッケージ ファミリ名" の出力が表示され、インストールされ、ID で実行されていることを確認します。
ヒント
(コード変更後など) アプリを再パッケージ化する必要がある場合は、Versionをもう一度実行する前に、Package.appxmanifestのwinapp packをインクリメントします。 Windowsインストールされているパッケージを更新するには、より高いバージョン番号が必要です。
ヒント
- 配布の準備ができたら、証明機関のコード署名証明書を使用して MSIX に署名し、ユーザーが自己署名証明書をインストールする必要がないようにすることができます。
- Azure の信頼された署名 サービスは、証明書を安全に管理し、CI/CD パイプラインへの署名を統合するための優れた方法です。
- Microsoft Storeは MSIX に署名します。送信前に署名する必要はありません。
- サポートするアーキテクチャ (x64、Arm64) ごとに 1 つずつ、複数の MSIX パッケージを作成する必要がある場合があります。 適切なジェネレーターとアーキテクチャ フラグを使用して CMake を構成します。
次のステップ
winget を使用して配布: MSIX をWindows パッケージ マネージャー Community Repository に送信しますMicrosoft Store に発行する :を使用してパッケージを送信する -
CI/CD の設定:
setup-WinAppCliGitHub Action を使用して、パイプライン内のパッケージングを自動化します Explore Windows API : パッケージ ID を使用して、 これで、Notifications 、on-device AI 、およびその他のidentity 依存 API
Windows developer