Skip to content

Commit 0f3da02

Browse files
committed
adding initial version of winapp cli docs
1 parent 6efeccb commit 0f3da02

18 files changed

Lines changed: 2782 additions & 2 deletions

hub/apps/toc.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,40 @@ items:
7070
href: windows-app-sdk/downloads-archive.md
7171
- name: WinUI
7272
href: winui/winui3/index.md
73+
- name: Windows App Development CLI
74+
items:
75+
- name: Overview
76+
href: winapp-cli/index.md
77+
- name: CLI reference
78+
href: winapp-cli/usage.md
79+
- name: Framework guides
80+
items:
81+
- name: Overview
82+
href: winapp-cli/guides/index.md
83+
- name: C++
84+
href: winapp-cli/guides/cpp.md
85+
- name: .NET
86+
href: winapp-cli/guides/dotnet.md
87+
- name: Electron
88+
items:
89+
- name: Setup
90+
href: winapp-cli/guides/electron-setup.md
91+
- name: Packaging
92+
href: winapp-cli/guides/electron-packaging.md
93+
- name: C++ notification addon
94+
href: winapp-cli/guides/electron-cpp-notification-addon.md
95+
- name: Phi Silica addon
96+
href: winapp-cli/guides/electron-phi-silica-addon.md
97+
- name: WinML addon
98+
href: winapp-cli/guides/electron-winml-addon.md
99+
- name: Flutter
100+
href: winapp-cli/guides/flutter.md
101+
- name: Rust
102+
href: winapp-cli/guides/rust.md
103+
- name: Tauri
104+
href: winapp-cli/guides/tauri.md
105+
- name: Packaging a CLI executable
106+
href: winapp-cli/guides/packaging-cli.md
73107
- name: Get started with WinUI
74108
items:
75109
- name: Quick start

hub/apps/winapp-cli/guides/cpp.md

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
---
2+
title: Using winapp CLI with C++ and CMake
3+
description: Learn how to use the winapp CLI with a C++ application to add package identity, access Windows APIs, and package as MSIX.
4+
ms.date: 02/20/2026
5+
ms.topic: how-to
6+
---
7+
8+
# Using winapp CLI with C++ and CMake
9+
10+
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.
11+
12+
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.
13+
14+
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.
15+
16+
## Prerequisites
17+
18+
1. **Build Tools**: Use a compiler toolchain supported by CMake. This example uses Visual Studio. You can install the community edition with:
19+
20+
```powershell
21+
winget install --id Microsoft.VisualStudio.Community --source winget --override "--add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --passive --wait"
22+
```
23+
24+
Reboot after installation.
25+
26+
2. **CMake**: Install CMake:
27+
28+
```powershell
29+
winget install Kitware.CMake --source winget
30+
```
31+
32+
3. **winapp CLI**: Install the `winapp` CLI via winget:
33+
34+
```powershell
35+
winget install Microsoft.winappcli --source winget
36+
```
37+
38+
## 1. Create a new C++ app
39+
40+
Start by creating a simple C++ application. Create a new directory for your project:
41+
42+
```powershell
43+
mkdir cpp-app
44+
cd cpp-app
45+
```
46+
47+
Create a `main.cpp` file with a basic "Hello, world!" program:
48+
49+
```cpp
50+
#include <iostream>
51+
52+
int main() {
53+
std::cout << "Hello, world!" << std::endl;
54+
return 0;
55+
}
56+
```
57+
58+
Create a `CMakeLists.txt` file to configure the build:
59+
60+
```cmake
61+
cmake_minimum_required(VERSION 3.20)
62+
project(cpp-app)
63+
64+
set(CMAKE_CXX_STANDARD 20)
65+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
66+
67+
add_executable(cpp-app main.cpp)
68+
```
69+
70+
Build and run it to make sure everything is working:
71+
72+
```powershell
73+
cmake -B build
74+
cmake --build build --config Debug
75+
.\build\Debug\cpp-app.exe
76+
```
77+
78+
## 2. Update code to check identity
79+
80+
Update the app to check if it's running with package identity using the Windows Runtime C++ API.
81+
82+
First, update your `CMakeLists.txt` to link against the Windows App Model library:
83+
84+
```cmake
85+
cmake_minimum_required(VERSION 3.20)
86+
project(cpp-app)
87+
88+
set(CMAKE_CXX_STANDARD 20)
89+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
90+
91+
add_executable(cpp-app main.cpp)
92+
93+
# Link Windows Runtime libraries
94+
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
95+
```
96+
97+
Next, replace the contents of `main.cpp`:
98+
99+
```cpp
100+
#include <iostream>
101+
#include <windows.h>
102+
#include <appmodel.h>
103+
104+
int main() {
105+
UINT32 length = 0;
106+
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
107+
108+
if (result == ERROR_INSUFFICIENT_BUFFER) {
109+
std::wstring familyName;
110+
familyName.resize(length);
111+
112+
result = GetCurrentPackageFamilyName(&length, familyName.data());
113+
114+
if (result == ERROR_SUCCESS) {
115+
std::wcout << L"Package Family Name: " << familyName.c_str() << std::endl;
116+
} else {
117+
std::wcout << L"Error retrieving Package Family Name" << std::endl;
118+
}
119+
} else {
120+
std::cout << "Not packaged" << std::endl;
121+
}
122+
123+
return 0;
124+
}
125+
```
126+
127+
## 3. Run without identity
128+
129+
Rebuild and run the app:
130+
131+
```powershell
132+
cmake --build build --config Debug
133+
.\build\Debug\cpp-app.exe
134+
```
135+
136+
You should see "Not packaged". This confirms that the standard executable is running without any package identity.
137+
138+
## 4. Initialize project with winapp CLI
139+
140+
The `winapp init` command sets up everything you need: app manifest, assets, and optionally Windows App SDK headers for C++ development.
141+
142+
```powershell
143+
winapp init
144+
```
145+
146+
When prompted:
147+
148+
- **Package name**: Press Enter to accept the default (cpp-app)
149+
- **Publisher name**: Press Enter to accept the default or enter your name
150+
- **Version**: Press Enter to accept 1.0.0.0
151+
- **Entry point**: Press Enter to accept the default (cpp-app.exe)
152+
- **Setup SDKs**: Select "Stable SDKs" to download Windows App SDK and generate headers
153+
154+
This command creates:
155+
156+
- `appxmanifest.xml` and `Assets` folder for your app identity
157+
- A `.winapp` folder with Windows App SDK headers and libraries
158+
- A `winapp.yaml` configuration file for pinning SDK versions
159+
160+
## 5. Debug with identity
161+
162+
To test features that require identity without fully packaging the app, use `winapp create-debug-identity`:
163+
164+
1. **Build the executable**:
165+
166+
```powershell
167+
cmake --build build --config Debug
168+
```
169+
170+
2. **Apply debug identity**:
171+
172+
```powershell
173+
winapp create-debug-identity .\build\Debug\cpp-app.exe
174+
```
175+
176+
3. **Run the executable**:
177+
178+
```powershell
179+
.\build\Debug\cpp-app.exe
180+
```
181+
182+
You should now see output similar to:
183+
184+
```
185+
Package Family Name: cpp-app_12345abcde
186+
```
187+
188+
### Automating debug identity (optional)
189+
190+
Add a post-build command to your `CMakeLists.txt` to automatically apply debug identity:
191+
192+
```cmake
193+
add_custom_command(TARGET cpp-app POST_BUILD
194+
COMMAND $<$<CONFIG:Debug>:winapp>
195+
$<$<CONFIG:Debug>:create-debug-identity>
196+
$<$<CONFIG:Debug>:$<TARGET_FILE:cpp-app>>
197+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
198+
COMMAND_EXPAND_LISTS
199+
COMMENT "Applying debug identity to executable..."
200+
)
201+
```
202+
203+
## 6. Using Windows App SDK (optional)
204+
205+
If you selected to setup the SDKs during `winapp init`, you have access to Windows App SDK headers in the `.winapp/include` folder.
206+
207+
Update your `CMakeLists.txt` to include the headers:
208+
209+
```cmake
210+
# Add Windows App SDK include directory
211+
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
212+
```
213+
214+
Update `main.cpp` to use the Windows App Runtime API:
215+
216+
```cpp
217+
#include <iostream>
218+
#include <windows.h>
219+
#include <appmodel.h>
220+
#include <winrt/Microsoft.Windows.ApplicationModel.WindowsAppRuntime.h>
221+
222+
int main() {
223+
winrt::init_apartment();
224+
225+
UINT32 length = 0;
226+
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
227+
228+
if (result == ERROR_INSUFFICIENT_BUFFER) {
229+
std::wstring familyName;
230+
familyName.resize(length);
231+
232+
result = GetCurrentPackageFamilyName(&length, familyName.data());
233+
234+
if (result == ERROR_SUCCESS) {
235+
std::wcout << L"Package Family Name: " << familyName.c_str() << std::endl;
236+
237+
auto runtimeVersion = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::RuntimeInfo::AsString();
238+
std::wcout << L"Windows App Runtime Version: " << runtimeVersion.c_str() << std::endl;
239+
}
240+
} else {
241+
std::cout << "Not packaged" << std::endl;
242+
}
243+
244+
return 0;
245+
}
246+
```
247+
248+
## 7. Restore headers when needed
249+
250+
The `.winapp` folder is automatically added to `.gitignore`. When others clone your project, they need to restore these files:
251+
252+
```powershell
253+
winapp restore
254+
winapp cert generate --if-exists skip
255+
```
256+
257+
## 8. Package with MSIX
258+
259+
Once you're ready to distribute, package as MSIX:
260+
261+
1. **Build for release**:
262+
263+
```powershell
264+
cmake --build build --config Release
265+
```
266+
267+
2. **Prepare package directory**:
268+
269+
```powershell
270+
mkdir dist
271+
copy .\build\Release\cpp-app.exe .\dist\
272+
```
273+
274+
3. **Generate a development certificate**:
275+
276+
```powershell
277+
winapp cert generate --if-exists skip
278+
```
279+
280+
4. **Package and sign**:
281+
282+
```powershell
283+
winapp pack .\dist --cert .\devcert.pfx
284+
```
285+
286+
5. **Install the certificate** (run as administrator):
287+
288+
```powershell
289+
winapp cert install .\devcert.pfx
290+
```
291+
292+
6. **Install and run**:
293+
294+
```powershell
295+
Add-AppxPackage .\cpp-app.msix
296+
cpp-app
297+
```
298+
299+
> [!TIP]
300+
> - Sign your MSIX with a code signing certificate from a Certificate Authority for production distribution.
301+
> - The Microsoft Store signs the MSIX for you, no need to sign before submission.
302+
> - You may need separate MSIX packages for each architecture you support (x64, Arm64).
303+
304+
## Related topics
305+
306+
- [winapp CLI reference](../usage.md)
307+
- [winapp CLI overview](../index.md)
308+
- [Windows App SDK documentation](/windows/apps/windows-app-sdk/)

0 commit comments

Comments
 (0)