Many Windows APIs (push notifications, background tasks, share target, startup tasks, Windows AI APIs) require your app to have package identity. During development, you don't want to build a full MSIX installer every time you test — winapp provides two commands to give your app identity on the fly.
Using Visual Studio with a packaging project? If you are already using Visual Studio for your packaged project, you likely don't need winapp for debugging. Visual Studio already handles package registration, identity, AUMID activation, debugger attachment, and activation-code debugging — all from F5. It also offers Debug → Other Debug Targets → Debug Installed App Package for advanced scenarios. The workflows below are most useful for VS Code users, terminal-based workflows, and frameworks that VS doesn't natively package (Rust, Flutter, Tauri, Electron, plain C++).
winapp run |
create-debug-identity |
|
|---|---|---|
| What it registers | Full loose layout package (entire folder) | Sparse package (single exe) |
| How the app launches | Launched by winapp (AUMID activation or execution alias) | You launch the exe yourself (command line, IDE, etc.) |
| Simulates MSIX install | Yes — closest to production behavior | No — sparse identity only |
| Files stay in place | Copied to an AppX layout directory | Yes — exe stays at its original path |
| Identity scope | Entire folder contents (exe, DLLs, assets) | Single executable |
| Debugger-friendly | Attach to PID after launch, or use --no-launch then launch via alias |
Launch directly from your IDE's debugger — the exe has identity regardless |
| Console app support | --with-alias keeps stdin/stdout in terminal |
Run exe directly in terminal |
| Best for | Most frameworks (.NET, C++, Rust, Flutter, Tauri) | Electron, or when you need full IDE debugger control (F5) |
Use winapp run for most development workflows. It simulates a real MSIX install — your app gets the same identity, capabilities, and file associations it would have in production.
# Build your app, then:
winapp run .\build\output- Your exe is separate from your build output — e.g., Electron apps where
electron.exelives innode_modules/ - You need to debug startup code and can't attach a debugger fast enough after AUMID launch
- With some debuggers where you can't launch with AUMID and need identity on the launched process —
create-debug-identityregisters the exe so it has identity no matter how it's started - You're testing sparse package behavior specifically (AllowExternalContent, TrustedLaunch)
# Register identity for an exe, then launch it however you want:
winapp create-debug-identity .\bin\Debug\myapp.exe
.\bin\Debug\myapp.exe # or F5 in your IDEThe simplest workflow — build, run with identity, done.
winapp run .\build\DebugWinapp registers the folder as a loose layout package and launches the app. Identity-requiring APIs work immediately. This covers the majority of development and testing scenarios.
For console apps that need stdin/stdout in the current terminal, add --with-alias:
winapp run .\build\Debug --with-aliasLaunch with winapp run, note the PID, then attach your IDE's debugger.
winapp run .\build\Debug
# Output: Process ID: 12345Then in your IDE:
- VS Code: Run and Debug → select "Attach" configuration (see IDE setup below)
- WinDbg:
windbg -p 12345
Limitation: You'll miss any code that runs before you attach. For startup debugging, use Scenario D (
create-debug-identity).
Use --no-launch to register the package, then launch the app through its AUMID (reported by run) or execution alias from your IDE.
Step 1: Register the package without launching:
winapp run .\build\Debug --no-launchStep 2: Configure your IDE to launch via the AUMID or the execution alias (not the exe directly).
- Launching with AUMID: Use the command
start shell:AppsFolder\<AUMID>.winapp runoutputs the AUMID when the app is registered. - Launching with the alias: The alias must be defined in your manifest (
Package.appxmanifestpreferred,appxmanifest.xmlalso supported).
Important: Simply launching the exe in the build folder will not give it identity. The app must be started via AUMID activation or its execution alias. This is how loose layout packages work - identity is tied to the activation path, not the exe file.
This is the best approach for debugging startup code with full IDE control - your IDE's debugger controls the process from the very first instruction, and the exe has identity no matter how it's launched.
winapp create-debug-identity .\build\Debug\myapp.exeNow launch the exe any way you like — from the terminal, from VS Code's F5, from a script. The exe has identity because Windows registered a sparse package pointing directly at it.
How it differs from
winapp run: Withcreate-debug-identity, identity is tied to the exe itself (viaAdd-AppxPackage -ExternalLocation). Withwinapp run, identity is tied to the loose layout package — the app must be launched through AUMID or an alias. This makescreate-debug-identitythe better choice when you need your IDE to launch and debug the exe directly.
This is also the best approach for Electron apps where the exe path differs from your source directory.
Capture OutputDebugString messages and first-chance exceptions inline. Framework noise (WinUI, COM, DirectX internal traces) is filtered from the console so only your app's debug messages appear. Everything is still written to the log file for full investigation.
If the app crashes, a minidump is captured and analyzed automatically:
winapp run .\build\Debug --debug-outputOn crash, the output includes the exception type, message, and stack trace with source file and line numbers (resolved from PDBs in your build output folder). Managed (.NET) crashes are analyzed instantly with no external tools. Native (C++/WinRT) crashes show module names and offsets; add --symbols to download PDB symbols for full function names:
winapp run .\build\Debug --debug-output --symbolsImportant: This attaches winapp as the debugger. Windows only allows one debugger per process, so you cannot also attach Visual Studio, VS Code, or WinDbg.
The WinApp VS Code extension provides a custom winapp debug type that launches your app with package identity and attaches the debugger — all from a single F5 press.
Add a winapp launch configuration to .vscode/launch.json:
When you press F5:
- The extension scans your workspace for build output directories containing
.exefiles. - You select the build folder to run (or set
inputFolderto skip the prompt). - It launches your app via
winapp runto give it package identity. - A child debug session attaches to the running process using the debugger you specified.
Once the debugger attaches, you get the full VS Code debugging experience — set breakpoints by clicking the gutter, step through code line-by-line (F10), step into functions (F11), inspect variables in the Variables pane, and evaluate expressions in the Debug Console. The app runs with package identity throughout, so identity-dependent APIs behave exactly as they would in production.
Important: The
winappdebug type does not build your project automatically. After making code changes, rebuild before pressing F5.
To avoid forgetting to rebuild, add a preLaunchTask that builds your project before every debug session:
- Define a build task in
.vscode/tasks.json(example for .NET):{ "version": "2.0.0", "tasks": [ { "label": "build", "command": "dotnet", "type": "process", "args": ["build", "${workspaceFolder}"], "problemMatcher": "$msCompile" } ] } - Reference it in your
launch.json:{ "type": "winapp", "request": "launch", "name": "WinApp: Launch and Attach", "preLaunchTask": "build" }
| Property | Type | Default | Description |
|---|---|---|---|
inputFolder |
string | Path to the build output folder containing your app binaries (e.g., ${workspaceFolder}/bin/Debug/net8.0-windows10.0.22621). If not set, you will be prompted to select a folder. |
|
manifest |
string | Path to an AppX manifest file (e.g., AppxManifest.xml, Package.appxmanifest, or appxmanifest.xml). If not set, the CLI auto-detects from the input folder or current directory. |
|
debuggerType |
string | coreclr |
Underlying debugger to use (coreclr, cppvsdbg, or node). |
workingDirectory |
string | workspace folder | Working directory for the application. |
args |
string | Command-line arguments to pass to the application. | |
outputAppxDirectory |
string | Output directory for the loose-layout package. Defaults to an AppX folder inside the input folder. |
|
port |
number | 9229 |
(node only) The port used for the Node.js --inspect listener and the attach connection. Override when the default port is already in use. |
debuggerType |
Language | Required Extension |
|---|---|---|
coreclr (default) |
C# / .NET | C# Dev Kit |
cppvsdbg |
C / C++ | C/C++ |
node |
Node.js / Electron | Built-in |
Example for a C++ project:
{
"type": "winapp",
"request": "launch",
"name": "WinApp: Launch C++ App",
"debuggerType": "cppvsdbg"
}If you need to debug startup code from the very first instruction, the F5 attach approach may miss early code. Instead, use the WinApp: Create Debug Identity command from the Command Palette (Ctrl+Shift+P) to register a sparse package for your executable, then launch it with your standard debugger:
{
"name": "Launch (with identity)",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/bin/Debug/net8.0-windows10.0.22621/myapp.exe"
}Since create-debug-identity registers identity on the exe itself, the app has identity no matter how it's launched — including from a standard VS Code launch configuration.
If you prefer to launch with winapp run from the terminal and then attach, use a standard attach configuration:
{
"name": "Attach to Process",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}For C++/Rust, use "type": "cppvsdbg" (MSVC) or "type": "lldb" (LLDB):
{
"name": "Attach (C++)",
"type": "cppvsdbg",
"request": "attach",
"processId": "${command:pickProcess}"
}When you're done testing, run WinApp: Unregister Package from the Command Palette to remove sideloaded development packages without leaving VS Code.
{ "version": "0.2.0", "configurations": [ { "type": "winapp", "request": "launch", "name": "WinApp: Launch and Attach" } ] }