Skip to content

Conversation

@yeelam-gordon
Copy link
Contributor

Background

According to this public doc:
https://learn.microsoft.com/en-us/windows/ai/apis/get-started?tabs=winget%2Cwinui%2Cwinui2
Every dev need to do 3 extra steps before calling AI APIs:
image
I am not sure if anyone will read this "get-started" step 3 carefully, but at least I don't aware that at all a month ago, and not sure spend me how much time to figure it out on my project.

Fix

In minimal, let's fix the template first. Other Vibe coding Troubleshooting is TBD for existing projects in the world.
This pull request updates several packaged app manifest templates for both C# and C++ desktop projects to support new system AI model capabilities. The changes ensure that new projects created from these templates can declare and use system AI models and are compatible with the most recent Windows features.
Fore sure, there are other circumstance, e.g. what platform SDK VS has, does it run on NPU machine etc which it doesn't mean this change can help for everything, but at least our template update is a good start for less fraction.

Manifest capability and compatibility updates:

  • Added the systemai XML namespace and included systemai:Capability Name="systemAIModels" in the <Capabilities> section to enable packaged apps to declare usage of system AI models. [1] [2] [3] [4] [5] [6]
  • Updated the IgnorableNamespaces attribute to include systemai, ensuring the new namespace is recognized and ignored where appropriate. [1] [2] [3]
  • Increased the MaxVersionTested for TargetDeviceFamily entries from 10.0.19041.0 to 10.0.26226.0 to target the latest Windows 10 SDK, improving compatibility with newer Windows releases. [1] [2] [3]
  • Applied these changes consistently across all relevant manifest templates for C# and C++ desktop project types, including packaged apps, single project packaged apps, and unit test apps. [1] [2] [3]

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR updates Visual Studio project templates for C# and C++/WinRT desktop applications to enable system AI model capabilities by default, eliminating the need for developers to manually configure manifests for AI API access.

Key Changes:

  • Added systemai namespace declaration and systemAIModels capability to all packaged app manifests
  • Updated MaxVersionTested from Windows SDK 10.0.19041.0 to 10.0.26226.0
  • Applied changes consistently across C# and C++/WinRT templates for unit tests, single-project, and multi-project packaged apps

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
dev/VSIX/ProjectTemplates/Desktop/CppWinRT/UnitTestApp/Package-native.appxmanifest Added systemai namespace and capability to C++/WinRT unit test template; updated target SDK version
dev/VSIX/ProjectTemplates/Desktop/CppWinRT/SingleProjectPackagedApp/Package-native.appxmanifest Added systemai namespace and capability to C++/WinRT single-project template; updated target SDK version
dev/VSIX/ProjectTemplates/Desktop/CppWinRT/PackagedApp/WapProj/Package-managed.appxmanifest Added systemai namespace and capability to C++/WinRT packaged app template; updated target SDK version
dev/VSIX/ProjectTemplates/Desktop/CSharp/UnitTestApp/Package-managed.appxmanifest Added systemai namespace and capability to C# unit test template; updated target SDK version
dev/VSIX/ProjectTemplates/Desktop/CSharp/SingleProjectPackagedApp/Package-managed.appxmanifest Added systemai namespace and capability to C# single-project template; updated target SDK version
dev/VSIX/ProjectTemplates/Desktop/CSharp/PackagedApp/WapProj/Package-managed.appxmanifest Added systemai namespace and capability to C# packaged app template; updated target SDK version

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@yeelam-gordon
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@Scottj1s
Copy link
Member

Scottj1s commented Nov 14, 2025

Hi Gordon, this PR works for C++ projects, but not C#. The explanation is a bit convoluted...

Here are the results of the same experiment with C++ and C# projects and how the final appxmanifest.xml's TargetDeviceFamily is generated:

vcxproj:

    <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>
package.appxmanifest:
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.26226.0" />
appxmanifest.xml:
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.26226.0" />
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
binlog:
    <TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformVersion>
    <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>

csproj:

    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
package.appxmanifest:
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.26226.0" />
appxmanifest.xml:
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
binlog:
    <TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformVersion>
    <TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>

Several things are going on here. C++ sets TargetPlatformIdentifier to UAP and C# sets it to Windows, which influences the addition of the TargetDeviceFamily downstream. C++ adds Universal TDF (for UAP TPI) and C# adds Desktop TDF (for Windows TPI). In both cases, the MinVersion and MaxVersionTested are replaced with the TPV/TPMV values from the project file. In the case of C++, the existing Windows.Desktop TDF is carried along unchanged. But in the case of C#, the Windows.Desktop TDF is updated, breaking the required MVT of 26226.

Note also that due to a bug in the SingleProject extension, these do not work as expected (and documented):

    <AppxOSMinVersionReplaceManifestVersion>false</AppxOSMinVersionReplaceManifestVersion>
    <AppxOSMaxVersionTestedReplaceManifestVersion>false</AppxOSMaxVersionTestedReplaceManifestVersion>

All our project templates should only target TDF Windows.Desktop, as that's the only SKU that WinAppSDK supports. We should remove Windows.Universal and update the C++ project templates to set TDI to Desktop to avoid adding Windows.Universal TDF.

Also, ideally we'd want the TPV/TPMV substitution behavior, as that's consistent with UWP and wapproj, and provides a single source of truth, and better visibility, for what the developer is targeting and testing. To that end, we would want to prompt the developer to select TPV on project creation, as we do for C++/WinRT templates, via Microsoft.VisualStudio.Universal.TemplateWizards.PlatformVersion.Wizard. Unfortunately, we don't have a 26226 SDK publicly available, so we can't yet rely on TPV to propagate to TDF MVT.

Related issues:
WinAppSDK repos need TargetDeviceFamily audit
Microsoft.Windows.SDK.BuildTools.MSIX does not support AppxOSMinVersionReplaceManifestVersion, AppxOSMaxVersionTestedReplaceManifestVersion

Copy link
Member

@Scottj1s Scottj1s left a comment

Choose a reason for hiding this comment

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

Need to address C#, and ideally remove addition of Universal TDF for C++ (see extended discussion)

@yeelam-gordon
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@yeelam-gordon yeelam-gordon force-pushed the user/yeelam/UpdateVSTemplate branch from 32ff71a to 0bf2783 Compare November 17, 2025 01:56
@yeelam-gordon
Copy link
Contributor Author

yeelam-gordon commented Nov 17, 2025

Hi Gordon, this PR works for C++ projects, but not C#. The explanation is a bit convoluted...

Here are the results of the same experiment with C++ and C# projects and how the final appxmanifest.xml's TargetDeviceFamily is generated:

vcxproj:

    <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>
package.appxmanifest:
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.26226.0" />
appxmanifest.xml:
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.26226.0" />
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
binlog:
    <TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformVersion>
    <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>

csproj:

    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
package.appxmanifest:
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.26226.0" />
appxmanifest.xml:
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
binlog:
    <TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformVersion>
    <TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>

Several things are going on here. C++ sets TargetPlatformIdentifier to UAP and C# sets it to Windows, which influences the addition of the TargetDeviceFamily downstream. C++ adds Universal TDF (for UAP TPI) and C# adds Desktop TDF (for Windows TPI). In both cases, the MinVersion and MaxVersionTested are replaced with the TPV/TPMV values from the project file. In the case of C++, the existing Windows.Desktop TDF is carried along unchanged. But in the case of C#, the Windows.Desktop TDF is updated, breaking the required MVT of 26226.

Note also that due to a bug in the SingleProject extension, these do not work as expected (and documented):

    <AppxOSMinVersionReplaceManifestVersion>false</AppxOSMinVersionReplaceManifestVersion>
    <AppxOSMaxVersionTestedReplaceManifestVersion>false</AppxOSMaxVersionTestedReplaceManifestVersion>

All our project templates should only target TDF Windows.Desktop, as that's the only SKU that WinAppSDK supports. We should remove Windows.Universal and update the C++ project templates to set TDI to Desktop to avoid adding Windows.Universal TDF.

Also, ideally we'd want the TPV/TPMV substitution behavior, as that's consistent with UWP and wapproj, and provides a single source of truth, and better visibility, for what the developer is targeting and testing. To that end, we would want to prompt the developer to select TPV on project creation, as we do for C++/WinRT templates, via Microsoft.VisualStudio.Universal.TemplateWizards.PlatformVersion.Wizard. Unfortunately, we don't have a 26226 SDK publicly available, so we can't yet rely on TPV to propagate to TDF MVT.

Related issues: WinAppSDK repos need TargetDeviceFamily audit Microsoft.Windows.SDK.BuildTools.MSIX does not support AppxOSMinVersionReplaceManifestVersion, AppxOSMaxVersionTestedReplaceManifestVersion

Thanks Scott for explain.
I am a kind of aware and testing on C# one when creating this PR:

  1. Our csproj template does NOT specify for WindowsTargetPlatformVersion, ONLY WindowsTargetPlatformMinVersion.
    As the result, it will pick the biggest SDK version installed, on my machine with 26226 SDK, it run without problem.
  2. Our vcxproj template DOES specify WindowsTargetPlatformVersion as 10 (exacly 10), the meaning should be the same, i.e. use the biggest version installed.
    Thus, the workaround:
<AppxOSMinVersionReplaceManifestVersion>false</AppxOSMinVersionReplaceManifestVersion>
<AppxOSMaxVersionTestedReplaceManifestVersion>false</AppxOSMaxVersionTestedReplaceManifestVersion>

Are for the situation my machine haven't installed 26226 SDK, but I still want my app manifest not being overwrite by lower version during build time.
I aware these workaround are too tricky to be added as part of template, thus I don't add it as part of the template.

Overall, I know the update above is just a "LITTLE" helping not many manual workaround is need, but at least on a machine with latest VS setup and NPU machine should be fine.

Hope it helps.

@Scottj1s
Copy link
Member

Thus, the workaround:

<AppxOSMinVersionReplaceManifestVersion>false</AppxOSMinVersionReplaceManifestVersion>
<AppxOSMaxVersionTestedReplaceManifestVersion>false</AppxOSMaxVersionTestedReplaceManifestVersion>

As mentioned, this actually doesn't work around anything, due to a bug in the single-project code (these properties are simply not implemented by our custom task). The reason C++ works is as I noted - because the single-project code is ignoring the Desktop TDF and modifying the unnecessary Universal TDF instead. I'm ok with taking incremental fixes - just want to make sure we're tracking remaining work.

@yeelam-gordon
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@yeelam-gordon yeelam-gordon merged commit 5fdc9d6 into main Dec 1, 2025
36 checks passed
@yeelam-gordon yeelam-gordon deleted the user/yeelam/UpdateVSTemplate branch December 1, 2025 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants