Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This guide demonstrates how to use the winapp CLI with a C++ application to debug with package identity and package your application as an MSIX.
Package identity is a core concept in the Windows app model. It allows your application to access specific Windows APIs (like Notifications, Security, AI APIs, etc.), have a clean install/uninstall experience, and more.
A standard executable (like one created with cmake --build) does not have package identity. This guide shows how to add it for debugging and then package it for distribution.
Prerequisites
Build Tools: Use a compiler toolchain supported by CMake. This example uses Visual Studio. You can install the community edition with:
winget install --id Microsoft.VisualStudio.Community --source winget --override "--add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --passive --wait"Reboot after installation.
CMake: Install CMake:
winget install Kitware.CMake --source wingetwinapp CLI: Install the
winappCLI via winget:winget install Microsoft.winappcli --source winget
1. Create a new C++ app
Start by creating a simple C++ application. Create a new directory for your project:
mkdir cpp-app
cd cpp-app
Create a main.cpp file with a basic "Hello, world!" program:
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
Create a CMakeLists.txt file to configure the build:
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)
Build and run it to make sure everything is working:
cmake -B build
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
2. Update code to check identity
Update the app to check if it's running with package identity using the Windows Runtime C++ API.
First, update your CMakeLists.txt to link against the Windows App Model library:
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)
# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
Next, replace the contents of main.cpp:
#include <iostream>
#include <windows.h>
#include <appmodel.h>
int main() {
UINT32 length = 0;
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
if (result == ERROR_INSUFFICIENT_BUFFER) {
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 {
std::cout << "Not packaged" << std::endl;
}
return 0;
}
3. Run without identity
Rebuild and run the app:
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
You should see "Not packaged". This confirms that the standard executable is running without any package identity.
4. Initialize project with winapp CLI
The winapp init command sets up everything you need: app manifest, assets, and optionally Windows App SDK headers for C++ development.
winapp init
When prompted:
- Package name: Press Enter to accept the default (cpp-app)
- Publisher name: Press Enter to accept the default or enter your name
- Version: Press Enter to accept 1.0.0.0
- Entry point: Press Enter to accept the default (cpp-app.exe)
- Setup SDKs: Select "Stable SDKs" to download Windows App SDK and generate headers
This command creates:
appxmanifest.xmlandAssetsfolder for your app identity- A
.winappfolder with Windows App SDK headers and libraries - A
winapp.yamlconfiguration file for pinning SDK versions
5. Debug with identity
To test features that require identity without fully packaging the app, use winapp create-debug-identity:
Build the executable:
cmake --build build --config DebugApply debug identity:
winapp create-debug-identity .\build\Debug\cpp-app.exeRun the executable:
.\build\Debug\cpp-app.exe
You should now see output similar to:
Package Family Name: cpp-app_12345abcde
Automating debug identity (optional)
Add a post-build command to your CMakeLists.txt to automatically apply debug identity:
add_custom_command(TARGET cpp-app POST_BUILD
COMMAND $<$<CONFIG:Debug>:winapp>
$<$<CONFIG:Debug>:create-debug-identity>
$<$<CONFIG:Debug>:$<TARGET_FILE:cpp-app>>
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND_EXPAND_LISTS
COMMENT "Applying debug identity to executable..."
)
6. Using Windows App SDK (optional)
If you selected to setup the SDKs during winapp init, you have access to Windows App SDK headers in the .winapp/include folder.
Update your CMakeLists.txt to include the headers:
# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
Update main.cpp to use the Windows App Runtime API:
#include <iostream>
#include <windows.h>
#include <appmodel.h>
#include <winrt/Microsoft.Windows.ApplicationModel.WindowsAppRuntime.h>
int main() {
winrt::init_apartment();
UINT32 length = 0;
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
if (result == ERROR_INSUFFICIENT_BUFFER) {
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;
auto runtimeVersion = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::RuntimeInfo::AsString();
std::wcout << L"Windows App Runtime Version: " << runtimeVersion.c_str() << std::endl;
}
} else {
std::cout << "Not packaged" << std::endl;
}
return 0;
}
7. Restore headers when needed
The .winapp folder is automatically added to .gitignore. When others clone your project, they need to restore these files:
winapp restore
winapp cert generate --if-exists skip
8. Package with MSIX
Once you're ready to distribute, package as MSIX:
Build for release:
cmake --build build --config ReleasePrepare package directory:
mkdir dist copy .\build\Release\cpp-app.exe .\dist\Generate a development certificate:
winapp cert generate --if-exists skipPackage and sign:
winapp pack .\dist --cert .\devcert.pfxInstall the certificate (run as administrator):
winapp cert install .\devcert.pfxInstall and run:
Add-AppxPackage .\cpp-app.msix cpp-app
Tip
- Sign your MSIX with a code signing certificate from a Certificate Authority for production distribution.
- The Microsoft Store signs the MSIX for you, no need to sign before submission.
- You may need separate MSIX packages for each architecture you support (x64, Arm64).
Related topics
Windows developer