Skip to content

winapp package: accept a C++ .vcxproj - #1122

Open
Zach Teutsch (zateutsch) wants to merge 3 commits into
mainfrom
zateutsch-package-accepts-vcxproj
Open

Zach Teutsch (zateutsch) wants to merge 3 commits into
mainfrom
zateutsch-package-accepts-vcxproj

Conversation

@zateutsch

@zateutsch Zach Teutsch (zateutsch) commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What and why

winapp run .\MyApp.vcxproj builds and launches a C++ app, but winapp package .\MyApp.vcxproj failed with a misleading error about sparse manifests. Now winapp package builds a .vcxproj with Visual Studio's MSBuild (the same build winapp run uses) and creates an MSIX from the build output in one step:

winapp package .\MyApp.vcxproj --generate-cert
winapp package .\MyApp.vcxproj -p Configuration=Debug -p Platform=ARM64 --cert .\devcert.pfx
  • Builds Release for the current architecture by default. -c / -p Configuration and --arch / -p Platform work the same way as in winapp run.
  • A packaged project (the Visual Studio WinUI Blank App (Packaged) template) is packaged with the AppxManifest.xml its build generates. Other application projects use an appxmanifest.xml from winapp init or --manifest. If none is found, the error says to run winapp init.
  • --framework and multiple --arch values are rejected with a clear message. To build a multi-architecture bundle, build each architecture and pass the output folders.
  • Passing any other file, such as a .sln, now says "'App.sln' is not a supported input. Pass a .csproj or .vcxproj project, a build output folder, or a sparse appxmanifest.xml." instead of the sparse-manifest error.

Fixes #1115

Before / after

Same sample (samples\cpp-winui-app), same command.

Before (winapp 0.7.1)

winapp package on a vcxproj fails with a sparse manifest error

After (this branch)

winapp package builds the vcxproj and creates a signed MSIX

Not tested / risks

  • An unpackaged C++ project (console or Win32 app with appxmanifest.xml from winapp init) was tested with unit tests only, not end to end.

Checklist

  • Tests added or updated
  • Tested locally on Windows
  • Docs, samples, and plugins/winapp/skills/ updated if user-facing behavior changed
Notes for reviewers

winapp packages the build output itself instead of running MSBuild's own MSIX packaging targets. This keeps signing, --output, --name, and other options consistent with folder mode and .csproj project mode. Multi-architecture bundles were left out to keep this change small; one build per architecture plus winapp package <x64-folder> <arm64-folder> already works.

Copilot AI balanced review requested due to automatic review settings October 19, 2026 20:24
@zateutsch Zach Teutsch (zateutsch) added the agent-preparing Agent is addressing feedback or completing required validation and CI label Oct 19, 2026
Comment thread src/winapp-CLI/WinApp.Cli.Tests/PackageCommandProjectModeTests.cs Fixed
Comment thread src/winapp-CLI/WinApp.Cli/Commands/PackageCommand.CppMode.cs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Packaging can replace the build-generated runtime dependency with an unrelated configured version, producing an app that fails to launch.

1 open issue
What changed in this PR

Adds direct C++ project packaging to winapp package, reusing the Visual Studio MSBuild path used by winapp run.

Changes:

  • Builds .vcxproj inputs and packages their output with generated or supplied manifests.
  • Validates unsupported options and improves unsupported-file errors.
  • Adds tests and updates help, documentation, and sample instructions.
File Description
src/​winapp-CLI/​WinApp.Cli/​Commands/​PackageCommand.cs Routes C++ inputs and updates help and errors.
src/​winapp-CLI/​WinApp.Cli/​Commands/​PackageCommand.CppMode.cs Implements C++ build-and-package flow.
src/​winapp-CLI/​WinApp.Cli.Tests/​PackageCommandProjectModeTests.cs Tests C++ packaging and validation.
src/​winapp-CLI/​WinApp.Cli.Tests/​PackageCommandFakeMsixTests.cs Updates expected validation text.
src/​winapp-CLI/​WinApp.Cli.Tests/​FakeMsixService.cs Captures executable arguments for assertions.
samples/​cpp-winui-app/​README.md Adds a packaging example.
plugins/​winapp/​skills/​winapp-package/​SKILL.md Documents C++ packaging workflows.
docs/​usage.md Documents C++ inputs, options, and limitations.
docs/​guides/​cpp.md Adds direct project packaging guidance.

Review effort: Balanced

Comment thread src/winapp-CLI/WinApp.Cli/Commands/PackageCommand.CppMode.cs
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Build Metrics Report

Validation passed. All required build and validation jobs succeeded.

Binary Sizes

Artifact Baseline Current Delta
CLI (ARM64) 65.05 MB 65.08 MB 📈 +35.5 KB (+0.05%)
CLI (x64) 64.97 MB 65.01 MB 📈 +33.5 KB (+0.05%)
MSIX (ARM64) 26.93 MB 26.92 MB 📉 -8.3 KB (-0.03%)
MSIX (x64) 28.55 MB 28.56 MB 📈 +13.6 KB (+0.05%)
NPM Package 56.12 MB 56.14 MB 📈 +21.5 KB (+0.04%)
NuGet Package 56.27 MB 56.30 MB 📈 +30.9 KB (+0.05%)

.NET Test Results (TRX reports)

Other suites are reflected in the overall validation status above.

✅ 10680 passed, 43 skipped out of 10723 tests in 1826.6s (+16 tests, -757.7s vs. baseline)

Test Coverage

✅ 87.4% line coverage, 81.5% branch coverage · ✅ no change vs. baseline

CLI Startup Time

69ms median (x64, winapp --version) · ✅ +9ms vs. baseline

Try This Build

Installs the MSIX for your architecture, replacing any previously installed build. Needs the GitHub CLI — the command offers to install it and sign you in if it is missing.

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) 1122
Switching between builds often?

Put the tool on your PATH once:

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) -AddToPath

Then this build is just:

winapp-pr 1122

Run winapp-pr with no arguments to pick from a list of open PRs.


Updated 2026-10-22 22:04:14 UTC · commit 4a8f814 · workflow run

Comment thread src/winapp-CLI/WinApp.Cli.Tests/MsixServiceRuntimeTests.cs Fixed
Comment thread src/winapp-CLI/WinApp.Cli.Tests/MsixServiceRuntimeTests.cs Fixed
@zateutsch
Zach Teutsch (zateutsch) force-pushed the zateutsch-package-accepts-vcxproj branch from ba9f033 to 4a41202 Compare October 21, 2026 17:34
@chiaramooney

Chiara Mooney (chiaramooney) commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Agent came back with one concern for the --self-contained scenario, but it seems like winapp will only hit this error if the project's vsxproj remains framework-dependent (i.e. <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained> isn't set) and they are expecting winapp package App.vcxproj --self-contained to convert it to self-contained during packaging.

Not sure how common that scenario is. Here is its note:

Self-contained C++ packaging cannot find the project's restored runtime

  • What is wrong: The resolved Windows App SDK directory reaches framework-dependent packaging, but not self-contained runtime bundling. That path instead searches for a .csproj or winapp.yaml in the current directory.

  • Show me: From the restored samples\cpp-winui-app directory, run winapp package .\CppWinUIApp.vcxproj --self-contained --no-sign. This project uses packages.config, not .csproj or winapp.yaml. The source path reaches SetupSelfContainedAsync without the resolved SDK directory and throws Windows App SDK Runtime MSIX directory not found. Ensure Windows App SDK is installed. Expected: bundle the runtime already restored for this project. This has not been runtime-reproduced.

  • Why it matters: The advertised flag cannot produce a self-contained installer for this project shape despite its runtime being restored.

  • Smallest fix: Forward windowsAppSdkPackageDirectory through PrepareRuntimeForPackagingAsync and SetupSelfContainedAsync. Use its tools\MSIX directory before the existing fallback, matching the resolution already used by framework-dependent packaging. Add a regression test for the packages.config-only project shape.

Otherwise PR looks good to me.

@zateutsch
Zach Teutsch (zateutsch) force-pushed the zateutsch-package-accepts-vcxproj branch from 4a41202 to 8696de4 Compare October 21, 2026 20:24
@zateutsch Zach Teutsch (zateutsch) added ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge and removed agent-preparing Agent is addressing feedback or completing required validation and CI labels Oct 21, 2026
@zateutsch
Zach Teutsch (zateutsch) force-pushed the zateutsch-package-accepts-vcxproj branch from 8696de4 to bde3e74 Compare October 22, 2026 20:16
@zateutsch Zach Teutsch (zateutsch) added agent-preparing Agent is addressing feedback or completing required validation and CI and removed ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge labels Oct 22, 2026
@chiaramooney

Copy link
Copy Markdown
Contributor

Agent came back with these concerns:

High: Self-contained packaging ignores the runtime used by the C++ build

What is wrong: --self-contained does not change the native build. Packaging instead tries to copy in the runtime afterward, but that lookup ignores the evaluated Windows App SDK directory passed by this PR.

Show me: A framework-dependent C++ project imports its SDK through shared build properties, with no local winapp.yaml or C# project:

PowerShell

winapp package .\App.vcxproj --self-contained --no-sign

The harness supplied an evaluated SDK directory containing a runtime package. Packaging still reported No Microsoft.WindowsAppSDK package found, then exited 1 with Runtime files not found.

Why it matters: A project whose build already identifies its runtime cannot produce the requested self-contained package.

Smallest fix: Pass the evaluated SDK directory through self-contained runtime setup, not only through framework-dependency rewriting.

Location: src\winapp-CLI\WinApp.Cli\Commands\PackageCommand.CppMode.cs:194-202

High: Packaging an explicit C++ project can restore an unrelated C# project

What is wrong: The MSIX call omits both projectFile and noRestore. Dependency discovery therefore searches the current directory for a C# project instead of inspecting the selected C++ project.

Show me: With Helper.csproj in the current directory:

PowerShell

winapp package .\Native\App.vcxproj --no-build --no-restore

The harness observed Helper.csproj executing its restore target despite --no-restore. Expected: package Native without restoring Helper.

Why it matters: The command can contact feeds and change unrelated project files. The unrelated dependency graph can also influence runtime-component entries added to the native package manifest.

Smallest fix: Pass projectFile: project and noRestore: noRestore. The existing package reader already handles .vcxproj by reading packages.config without invoking dotnet.

winapp package .\MyApp.vcxproj now builds the project with Visual Studio's
MSBuild (the same build winapp run uses) and packages the build output.
Packaged WinUI projects use their generated AppxManifest.xml and appxrecipe;
other application projects use an appxmanifest.xml from winapp init or
--manifest. --framework and multi-arch bundles are rejected for C++.

Unsupported file inputs now say which inputs are supported instead of
reporting a misleading sparse-manifest error.

Fixes #1115

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ad679915-8632-4530-8c49-58683247cf14
winapp package App.vcxproj now resolves the runtime dependency from the
Windows App SDK the build imported, instead of the version winapp.yaml
in the current folder names.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ad679915-8632-4530-8c49-58683247cf14
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ad679915-8632-4530-8c49-58683247cf14
@zateutsch
Zach Teutsch (zateutsch) force-pushed the zateutsch-package-accepts-vcxproj branch from bde3e74 to 4a8f814 Compare October 22, 2026 21:22
@zateutsch Zach Teutsch (zateutsch) added ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge and removed agent-preparing Agent is addressing feedback or completing required validation and CI labels Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: winapp package should accept a C++ .vcxproj like winapp run does

3 participants