Skip to content

Commit 639a7c7

Browse files
authored
Merge branch 'main' into zt/476-smart-init
2 parents d149d4d + c81824d commit 639a7c7

16 files changed

Lines changed: 1139 additions & 125 deletions

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Additional guides:
8383
| **Setup** | [init](usage.md#init), [restore](usage.md#restore), [update](usage.md#update) |
8484
| **Identity & Debugging** | [run](usage.md#run), [create-debug-identity](usage.md#create-debug-identity), [unregister](usage.md#unregister) |
8585
| **Packaging** | [pack](usage.md#pack) |
86-
| **Manifests** | [manifest generate](usage.md#manifest-generate), [manifest update-assets](usage.md#manifest), [manifest add-alias](usage.md#manifest-add-alias) |
86+
| **Manifests** | [manifest generate](usage.md#manifest-generate), [manifest update-assets](usage.md#manifest-update-assets), [manifest add-alias](usage.md#manifest-add-alias) |
8787
| **Certificates & Signing** | [cert generate](usage.md#cert-generate), [cert install](usage.md#cert-install), [sign](usage.md#sign), [create-external-catalog](usage.md#create-external-catalog) |
8888
| **Utilities** | [tool](usage.md#tool), [store](usage.md#store), [get-winapp-path](usage.md#get-winapp-path), [complete](usage.md#shell-completion) |
8989
| **UI Automation** | [ui](usage.md#ui) |

docs/guides/cpp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!-- mslearn: true -->
22
# Using winapp CLI with C++ and CMake
33

4-
This guide demonstrates how to use `winappcli` with a C++ application to debug with package identity and package your application as an MSIX.
4+
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.
55

66
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.
77

docs/guides/dotnet.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<!-- mslearn: true -->
22
# Using winapp CLI with .NET
33

4-
> This guide should work for most .NET projects types. The steps have been tested with both console and UI-based projects like WPF. For working examples, check out the [dotnet-app](../../samples/dotnet-app) (console) and [wpf-app](../../samples/wpf-app) (WPF) samples in the samples folder.
4+
> This guide should work for most .NET project types. The steps have been tested with both console and UI-based projects like WPF. For working examples, check out the [dotnet-app](../../samples/dotnet-app) (console) and [wpf-app](../../samples/wpf-app) (WPF) samples in the samples folder.
55
6-
This guide demonstrates how to use `winappcli` with a .NET application to debug with package identity and package your application as an MSIX.
6+
This guide demonstrates how to use the `winapp` CLI with a .NET application to debug with package identity and package your application as an MSIX.
77

88
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.
99

docs/guides/electron/cpp-notification-addon.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ npx winapp node create-addon
1717
```
1818

1919
> [!NOTE]
20-
> This command might prompt your to install Python or required Visual Studio tools if you don't already have them installed.
20+
> This command might prompt you to install Python or required Visual Studio tools if you don't already have them installed.
2121
2222
This creates a `nativeWindowsAddon/` folder with:
2323
- `nativeWindowsAddon.cc` - Your C++ code that will call Windows APIs

docs/guides/electron/packaging.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ The `--manifest` option is optional. If not provided, it will look for a Package
8686

8787
The `--cert` option is also optional. If not provided, the msix will not be signed.
8888

89-
The `--out` option is also optional. If not provided, the current directory will be used.
89+
The `--output` option is also optional. If not provided, the current directory will be used.
9090

9191
The MSIX package will be created as `./out/<your-app-name>.msix`.
9292

docs/guides/flutter.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
For a complete working example, check out the [Flutter sample](../../samples/flutter-app) in this repository.
55

6-
This guide demonstrates how to use `winappcli` with a Flutter application to add package identity and package your app as an MSIX.
6+
This guide demonstrates how to use the `winapp` CLI with a Flutter application to add package identity and package your app as an MSIX.
77

88
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.
99

docs/guides/rust.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!-- mslearn: true -->
22
# Using winapp CLI with Rust
33

4-
This guide demonstrates how to use `winappcli` with a Rust application to debug with package identity and package your application as an MSIX.
4+
This guide demonstrates how to use the `winapp` CLI with a Rust application to debug with package identity and package your application as an MSIX.
55

66
For a complete working example, check out the [Rust sample](../../samples/rust-app) in this repository.
77

docs/guides/tauri.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!-- mslearn: true -->
22
# Using winapp CLI with Tauri
33

4-
This guide demonstrates how to use `winappcli` with a Tauri application to debug with package identity and package your application as an MSIX.
4+
This guide demonstrates how to use the `winapp` CLI with a Tauri application to debug with package identity and package your application as an MSIX.
55

66
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.
77

docs/usage.md

Lines changed: 124 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ winapp init [base-directory] [options]
4444
- Creates Package.appxmanifest
4545
- Sets up build tools and enables developer mode
4646
- Updates .gitignore to exclude generated files
47-
- Stores sharable files in the global cache directory
47+
- Stores shareable files in the global cache directory
4848

4949
**Automatic project detection:**
5050

@@ -123,7 +123,7 @@ winapp restore [options]
123123
- Reads existing `winapp.yaml` configuration
124124
- Downloads/updates SDK packages to specified versions
125125
- Regenerates C++/WinRT headers and binaries
126-
- Stores sharable files in the global cache directory
126+
- Stores shareable files in the global cache directory
127127

128128
> [!NOTE]
129129
> For .NET projects initialized with `winapp init`, there is no `winapp.yaml`. Use `dotnet restore` to restore NuGet packages instead.
@@ -253,7 +253,7 @@ winapp create-debug-identity [entrypoint] [options]
253253

254254
**Options:**
255255

256-
- `--manifest <path>` - Path to AppxManifest.xml (default: auto-detect `Package.appxmanifest` or `appxmanifest.xml` in the current directory)
256+
- `--manifest <path>` - Path to the app manifest file, either `Package.appxmanifest` or `appxmanifest.xml` (default: auto-detect `Package.appxmanifest` or `appxmanifest.xml` in the current directory)
257257
- `--no-install` - Don't install the package after creation
258258
- `--keep-identity` - Keep the manifest identity as-is, without appending `.debug` to the package name and application ID
259259

@@ -339,6 +339,100 @@ winapp manifest generate
339339
winapp manifest generate ./src --package-name MyApp --publisher-name "CN=My Company" --if-exists overwrite
340340
```
341341

342+
#### manifest add-alias
343+
344+
Add an execution alias (`uap5:AppExecutionAlias`) to a Package.appxmanifest. This allows launching the packaged app from the command line by typing the alias name.
345+
346+
```bash
347+
winapp manifest add-alias [options]
348+
```
349+
350+
**Options:**
351+
352+
- `--name <alias>` - Alias name (e.g. `myapp.exe`). Default: inferred from the `Executable` attribute in the manifest.
353+
- `--manifest <path>` - Path to Package.appxmanifest (default: search current directory)
354+
- `--app-id <id>` - Application Id to add the alias to (default: first Application element)
355+
356+
**What it does:**
357+
358+
- Reads the manifest and infers the alias from the `Executable` attribute (preserving placeholders like `$targetnametoken$.exe`)
359+
- Adds the `uap5` namespace declaration if not already present
360+
- Adds an `<Extensions>` block with `<uap5:AppExecutionAlias>` inside the target Application element
361+
- If the alias already exists, reports it and exits successfully
362+
363+
**Examples:**
364+
365+
```bash
366+
# Add alias inferred from Executable attribute (e.g. $targetnametoken$.exe)
367+
winapp manifest add-alias
368+
369+
# Add alias with explicit name
370+
winapp manifest add-alias --name myapp.exe
371+
372+
# Add alias to specific manifest
373+
winapp manifest add-alias --manifest ./dist/Package.appxmanifest
374+
```
375+
376+
#### manifest update-assets
377+
378+
Generate all required MSIX image assets from a single source image.
379+
380+
```bash
381+
winapp manifest update-assets <image-path> [options]
382+
```
383+
384+
**Arguments:**
385+
386+
- `image-path` - Path to source image file (PNG, JPG, SVG, ICO, GIF, BMP, etc.)
387+
388+
**Options:**
389+
390+
- `--manifest <path>` - Path to Package.appxmanifest file (default: search current directory)
391+
- `--light-image <path>` - Path to a separate source image for light theme variants
392+
393+
**Description:**
394+
395+
Takes a single source image and generates a comprehensive set of MSIX image assets based on the manifest's asset references:
396+
397+
For each asset referenced in the manifest:
398+
- **5 scale variants** — base (no suffix), `.scale-125`, `.scale-150`, `.scale-200`, `.scale-400`
399+
400+
For the app icon (Square44x44Logo / AppList, 44×44 base):
401+
- **14 plated targetsize variants**`.targetsize-{16,20,24,30,32,36,40,48,60,64,72,80,96,256}`
402+
- **14 unplated targetsize variants**`.targetsize-{size}_altform-unplated`
403+
404+
Additionally:
405+
- **app.ico** — Multi-resolution ICO file (16, 24, 32, 48, 256) for shell integration. If an existing `.ico` file is found in the assets directory (e.g. `AppIcon.ico` from a project template), it is replaced in-place rather than creating a duplicate
406+
407+
With `--light-image`:
408+
- **Light theme targetsize variants**`.targetsize-{size}_altform-lightunplated` (app icon)
409+
- **Light theme scale variants**`.scale-{factor}_altform-colorful_theme-light` (tiles, store logo)
410+
411+
**SVG support:** SVG files are fully supported as source images. They are rendered as vectors directly at each target size, producing pixel-perfect results at all resolutions.
412+
413+
The command scales images proportionally while maintaining aspect ratio, centering them with transparent backgrounds when needed. Assets are saved to the `Assets` directory relative to the manifest location.
414+
415+
**Examples:**
416+
417+
```bash
418+
# Generate assets with auto-detected manifest
419+
winapp manifest update-assets mylogo.png
420+
421+
# Use an SVG source for best quality at all sizes
422+
winapp manifest update-assets mylogo.svg
423+
424+
# Specify manifest location explicitly
425+
winapp manifest update-assets mylogo.png --manifest ./dist/Package.appxmanifest
426+
427+
# Generate light theme variants from a separate image
428+
winapp manifest update-assets mylogo.png --light-image mylogo-light.png
429+
430+
# Use the same image for both (generates all MRT light theme qualifiers)
431+
winapp manifest update-assets mylogo.png --light-image mylogo.png
432+
433+
# With verbose output
434+
winapp manifest update-assets mylogo.png --verbose
435+
```
342436

343437
---
344438

@@ -368,6 +462,7 @@ winapp run <input-folder> [options]
368462
- `--unregister-on-exit` - Unregister the development package after the application exits. Only removes packages registered in development mode. Cannot be combined with `--no-launch`.
369463
- `--detach` - Launch the application and return immediately without waiting for it to exit. Useful for CI/automation where you need to interact with the app after launch. Prints the PID to stdout (or in JSON with `--json`). Cannot be combined with `--no-launch`, `--debug-output`, `--with-alias`, or `--unregister-on-exit`.
370464
- `--clean` - Remove the existing package's application data (LocalState, settings, etc.) before re-deploying. By default, application data is preserved across re-deployments.
465+
- `--json` - Format output as JSON for programmatic consumption (e.g. CI/automation). Useful with `--detach` to capture the PID. Cannot be combined with `--with-alias` or `--debug-output`.
371466

372467
**Application data persistence:**
373468

@@ -487,101 +582,6 @@ winapp unregister --json
487582

488583
---
489584

490-
#### manifest add-alias
491-
492-
Add an execution alias (`uap5:AppExecutionAlias`) to a Package.appxmanifest. This allows launching the packaged app from the command line by typing the alias name.
493-
494-
```bash
495-
winapp manifest add-alias [options]
496-
```
497-
498-
**Options:**
499-
500-
- `--name <alias>` - Alias name (e.g. `myapp.exe`). Default: inferred from the `Executable` attribute in the manifest.
501-
- `--manifest <path>` - Path to Package.appxmanifest (default: search current directory)
502-
- `--app-id <id>` - Application Id to add the alias to (default: first Application element)
503-
504-
**What it does:**
505-
506-
- Reads the manifest and infers the alias from the `Executable` attribute (preserving placeholders like `$targetnametoken$.exe`)
507-
- Adds the `uap5` namespace declaration if not already present
508-
- Adds an `<Extensions>` block with `<uap5:AppExecutionAlias>` inside the target Application element
509-
- If the alias already exists, reports it and exits successfully
510-
511-
**Examples:**
512-
513-
```bash
514-
# Add alias inferred from Executable attribute (e.g. $targetnametoken$.exe)
515-
winapp manifest add-alias
516-
517-
# Add alias with explicit name
518-
winapp manifest add-alias --name myapp.exe
519-
520-
# Add alias to specific manifest
521-
winapp manifest add-alias --manifest ./dist/Package.appxmanifest
522-
```
523-
524-
Generate all required MSIX image assets from a single source image.
525-
526-
```bash
527-
winapp manifest update-assets <image-path> [options]
528-
```
529-
530-
**Arguments:**
531-
532-
- `image-path` - Path to source image file (PNG, JPG, SVG, ICO, GIF, BMP, etc.)
533-
534-
**Options:**
535-
536-
- `--manifest <path>` - Path to Package.appxmanifest file (default: search current directory)
537-
- `--light-image <path>` - Path to a separate source image for light theme variants
538-
539-
**Description:**
540-
541-
Takes a single source image and generates a comprehensive set of MSIX image assets based on the manifest's asset references:
542-
543-
For each asset referenced in the manifest:
544-
- **5 scale variants** — base (no suffix), `.scale-125`, `.scale-150`, `.scale-200`, `.scale-400`
545-
546-
For the app icon (Square44x44Logo / AppList, 44×44 base):
547-
- **14 plated targetsize variants**`.targetsize-{16,20,24,30,32,36,40,48,60,64,72,80,96,256}`
548-
- **14 unplated targetsize variants**`.targetsize-{size}_altform-unplated`
549-
550-
Additionally:
551-
- **app.ico** — Multi-resolution ICO file (16, 24, 32, 48, 256) for shell integration. If an existing `.ico` file is found in the assets directory (e.g. `AppIcon.ico` from a project template), it is replaced in-place rather than creating a duplicate
552-
553-
With `--light-image`:
554-
- **Light theme targetsize variants**`.targetsize-{size}_altform-lightunplated` (app icon)
555-
- **Light theme scale variants**`.scale-{factor}_altform-colorful_theme-light` (tiles, store logo)
556-
557-
**SVG support:** SVG files are fully supported as source images. They are rendered as vectors directly at each target size, producing pixel-perfect results at all resolutions.
558-
559-
The command scales images proportionally while maintaining aspect ratio, centering them with transparent backgrounds when needed. Assets are saved to the `Assets` directory relative to the manifest location.
560-
561-
**Examples:**
562-
563-
```bash
564-
# Generate assets with auto-detected manifest
565-
winapp manifest update-assets mylogo.png
566-
567-
# Use an SVG source for best quality at all sizes
568-
winapp manifest update-assets mylogo.svg
569-
570-
# Specify manifest location explicitly
571-
winapp manifest update-assets mylogo.png --manifest ./dist/Package.appxmanifest
572-
573-
# Generate light theme variants from a separate image
574-
winapp manifest update-assets mylogo.png --light-image mylogo-light.png
575-
576-
# Use the same image for both (generates all MRT light theme qualifiers)
577-
winapp manifest update-assets mylogo.png --light-image mylogo.png
578-
579-
# With verbose output
580-
winapp manifest update-assets mylogo.png --verbose
581-
```
582-
583-
---
584-
585585
### cert
586586

587587
Generate, inspect, and install development certificates.
@@ -781,7 +781,7 @@ winapp tool signtool verify /pa MyApp.msix
781781

782782
### store
783783

784-
Run a Microsoft Store Developer CLI command. This command will download the Microsoft Store Developer CLI if not already downloaded. Learn more about the Microsoft Store Developer CLI here: ([https://aka.ms/msstoredevcli](https://aka.ms/msstoredevcli)).
784+
Run a Microsoft Store Developer CLI command. This command will download the Microsoft Store Developer CLI if not already downloaded. Learn more about the [Microsoft Store Developer CLI](https://aka.ms/msstoredevcli).
785785

786786
```bash
787787
winapp store [args...]
@@ -951,13 +951,37 @@ REM Set a custom location for winapp's global cache
951951
set WINAPP_CLI_CACHE_DIRECTORY=d:\temp\.winapp
952952
```
953953

954-
In **Powershell** and **pwsh**:
954+
In **PowerShell** and **pwsh**:
955955
```pwsh
956956
# Set a custom location for winapp's global cache
957957
$env:WINAPP_CLI_CACHE_DIRECTORY=d:\temp\.winapp
958958
```
959959

960960
Winapp will create this directory automatically when you run commands like `init` or `restore`.
961+
962+
### Update Checks
963+
964+
The winapp CLI periodically checks for new versions and displays a one-line notice when an update is available. This check runs in the background and adds no latency to commands.
965+
966+
Update checks are automatically disabled in CI environments (GitHub Actions, Azure Pipelines, etc.).
967+
968+
To manually disable update checks, set the `WINAPP_CLI_UPDATE_CHECK` environment variable to `0`.
969+
970+
In **cmd**:
971+
```cmd
972+
set WINAPP_CLI_UPDATE_CHECK=0
973+
```
974+
975+
In **PowerShell** and **pwsh**:
976+
```pwsh
977+
$env:WINAPP_CLI_UPDATE_CHECK = "0"
978+
```
979+
980+
To make this permanent:
981+
```powershell
982+
[System.Environment]::SetEnvironmentVariable('WINAPP_CLI_UPDATE_CHECK', '0', 'User')
983+
```
984+
961985
### ui
962986

963987
Inspect and interact with running Windows app UIs using UI Automation (UIA).

scripts/port-mslearn-docs.ps1

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,20 @@ foreach ($entry in $FileMapping.GetEnumerator()) {
346346

347347
# Escape bare <placeholder> patterns that MS Learn treats as HTML tags.
348348
# Matches <word>, <word-word>, <word word> not already inside backticks or code blocks.
349-
$content = [regex]::Replace($content, '<([\w][\w\s-]*)>', '&lt;$1&gt;')
349+
# Skip legitimate HTML tags whose closing form (</tag>) wouldn't be escaped by this rule,
350+
# which would otherwise produce mismatched &lt;tag&gt; ... </tag> pairs in the output.
351+
# Compare only the tag name (first token), so allowed tags with attributes like
352+
# <details open> are preserved as HTML instead of being partially escaped.
353+
$htmlPassthroughTags = @('details', 'summary', 'br', 'hr', 'sub', 'sup', 'kbd', 'b')
354+
$content = [regex]::Replace($content, '<([\w][\w\s-]*)>', {
355+
param($match)
356+
$tag = $match.Groups[1].Value
357+
$tagName = ($tag -split '\s+', 2)[0]
358+
if ($htmlPassthroughTags -contains $tagName.ToLowerInvariant()) {
359+
return $match.Value
360+
}
361+
return "&lt;$tag&gt;"
362+
})
350363

351364
# Rewrite image links first (before regular links, since ![...]() also matches [...]() regex)
352365
$content = [regex]::Replace($content, '!\[([^\]]*)\]\(([^)]+)\)', {

0 commit comments

Comments
 (0)