Adds a StripWindowsDesktopAppFromRuntimeConfig MSBuild target that
runs after GenerateBuildRuntimeConfigurationFiles and rewrites
TeamsISO.runtimeconfig.json to drop the implicit
Microsoft.WindowsDesktop.App framework reference. The .NET 8 SDK adds
that framework for any -windows TFM, but WinUI 3 doesn't use it and
including it in the runtimeconfig contributes to the broken
unpackaged activation path (one of the three suspects in the migration
plan's Phase 3).
Build log confirms the strip on every build:
Stripped Microsoft.WindowsDesktop.App from .../TeamsISO.runtimeconfig.json
Verified the runtimeconfig now reads:
{ "name": "Microsoft.NETCore.App", "version": "8.0.0" }
(no WindowsDesktop.App entry)
This didn't resolve the activation dialog on its own, but it's a
required step for any unpackaged WinUI 3 build and the next debugging
session can rule it out as a contributing cause.
142 lines
7.4 KiB
XML
142 lines
7.4 KiB
XML
<Project Sdk="Microsoft.NET.Sdk">
|
|
|
|
<!--
|
|
TeamsISO WinUI 3 host. Coexists with the WPF project (src/TeamsISO.App)
|
|
during the redesign migration. Shares the engine (TeamsISO.Engine) and
|
|
the NDI interop assembly via ProjectReference. Once the WinUI 3 build is
|
|
feature-complete and tested against a real Teams meeting, the WPF
|
|
project is retired and this becomes the only shipping host.
|
|
|
|
Target framework choice: net8.0-windows10.0.19041.0 is the minimum the
|
|
Windows App SDK supports cleanly. Going higher (e.g. 22621) would lock
|
|
out Win10 1809+ operators, which is undesirable for a broadcast tool
|
|
that still has to run on hardware in working broadcast suites.
|
|
|
|
Packaging mode: WindowsPackageType=None for "unpackaged" — the .exe
|
|
drops directly into Program Files via the existing MSI rather than
|
|
going through MSIX. The Windows App Runtime install becomes a prereq
|
|
of the MSI (or bootstrapped at startup), which matches how operators
|
|
install NDI Runtime today.
|
|
-->
|
|
<PropertyGroup>
|
|
<OutputType>WinExe</OutputType>
|
|
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
|
<SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
|
|
<RootNamespace>TeamsISO.App.WinUI</RootNamespace>
|
|
<AssemblyName>TeamsISO</AssemblyName>
|
|
<!--
|
|
Default app.manifest deferred: WinUI 3 emits its own manifest with the
|
|
DPI awareness + supportedOS GUIDs that match what we want. Our custom
|
|
manifest (kept in tree at app.manifest) describes the same intent but
|
|
doesn't currently merge cleanly with the framework-emitted manifest;
|
|
see docs/superpowers/plans/2026-05-12-winui3-migration.md for the
|
|
follow-up to reintroduce it via uap:VisualElements.
|
|
-->
|
|
<Platforms>x64;ARM64</Platforms>
|
|
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
|
|
<UseWinUI>true</UseWinUI>
|
|
<WindowsPackageType>None</WindowsPackageType>
|
|
<EnableMsixTooling>true</EnableMsixTooling>
|
|
<!--
|
|
Pinning the Windows SDK projection package: WindowsAppSDK 1.6 requires
|
|
Microsoft.Windows.SDK.NET.Ref >= 10.0.19041.38, but the .NET 8.0.301
|
|
SDK installed here ships an older Ref. Setting this explicitly avoids
|
|
having to upgrade the .NET SDK on the build host.
|
|
-->
|
|
<WindowsSdkPackageVersion>10.0.19041.38</WindowsSdkPackageVersion>
|
|
<!--
|
|
Disable the XAML compiler's auto-generated Program.Main so we can write
|
|
one that bootstraps the Windows App Runtime explicitly. The default
|
|
generated Main calls Application.Start directly, with no Bootstrap
|
|
initialization step — that's fine for packaged MSIX apps but blocks
|
|
unpackaged launch on a machine where the runtime is installed only as
|
|
a framework package. Program.cs in this project takes ownership of
|
|
Main and calls Bootstrap.TryInitialize(0x00010006) before Start.
|
|
-->
|
|
<DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants>
|
|
<!--
|
|
RuntimeIdentifier locks the build to win-x64 so runtime DLLs from
|
|
runtimes/win-x64/native (Microsoft.WindowsAppRuntime.Bootstrap.dll,
|
|
WebView2Loader.dll) flatten into the output dir alongside the .exe.
|
|
Without this, those DLLs sit in runtimes/win-x64/native/ and the
|
|
loader doesn't find them at activation time.
|
|
-->
|
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
|
<!--
|
|
Suppress the auto-injected UndockedRegFreeWinRT ModuleInitializer.
|
|
The bundled initializer P/Invokes Microsoft.WindowsAppRuntime.dll
|
|
during module load, BEFORE our Program.Main has a chance to call
|
|
Bootstrap.TryInitialize. Since the runtime DLL lives in the framework
|
|
MSIX package (not the output dir) on a framework-dependent install,
|
|
the P/Invoke fails to locate it and the .exe dies with the generic
|
|
"this application could not be started" dialog — diagnosed by
|
|
following the Microsoft.WindowsAppSDK.UndockedRegFreeWinRT.CS.targets
|
|
chain and reading the auto-init source. Our Program.cs handles the
|
|
bootstrap explicitly in the right order.
|
|
-->
|
|
<WindowsAppSdkUndockedRegFreeWinRTInitialize>false</WindowsAppSdkUndockedRegFreeWinRTInitialize>
|
|
<Nullable>enable</Nullable>
|
|
<ImplicitUsings>enable</ImplicitUsings>
|
|
<ApplicationIcon>Assets\teamsiso.ico</ApplicationIcon>
|
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
</PropertyGroup>
|
|
|
|
<!--
|
|
WindowsAppSDK 1.6 is the current LTS branch (Win10 1809-compatible at
|
|
a 10.0.17763 floor, which matches our SupportedOSPlatformVersion).
|
|
DataGrid lives in the older 7.x Community Toolkit because the 8.x line
|
|
dropped it; 7.1.2 still works on WinUI 3 / WindowsAppSDK 1.6 and is the
|
|
only currently-maintained free DataGrid for this stack.
|
|
-->
|
|
<ItemGroup>
|
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.250602001" />
|
|
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" Version="7.1.2" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<ProjectReference Include="..\TeamsISO.Engine\TeamsISO.Engine.csproj" />
|
|
<ProjectReference Include="..\TeamsISO.Engine.NdiInterop\TeamsISO.Engine.NdiInterop.csproj" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<Content Include="Assets\teamsiso.ico" />
|
|
<Content Include="Assets\dragon-mark.png" />
|
|
<Content Include="Assets\wild-dragon-wordmark.png" />
|
|
<Content Include="Assets\Fonts\Inter.ttf" />
|
|
<Content Include="Assets\Fonts\JetBrainsMono.ttf" />
|
|
</ItemGroup>
|
|
|
|
<!--
|
|
Post-build runtimeconfig patch. .NET 8 SDK adds Microsoft.WindowsDesktop.App
|
|
as an implicit framework reference for any -windows target framework moniker.
|
|
WinUI 3 doesn't use that framework; including it in runtimeconfig.json
|
|
forces the .NET host to resolve and load WindowsDesktop.App at startup,
|
|
which contributes to the WindowsAppSDK activation chain on unpackaged
|
|
apps. This target rewrites the generated runtimeconfig.json to drop the
|
|
WindowsDesktop.App entry so the host loads only NETCore.App.
|
|
|
|
The target runs after the framework-dependent build copies the
|
|
runtimeconfig.json to the output dir, before the bin/Debug/.../win-x64/
|
|
directory is final. It's a string-level rewrite — sufficient because the
|
|
JSON shape is stable across SDK versions and the WindowsDesktop.App
|
|
entry has a deterministic indent + sibling structure.
|
|
-->
|
|
<Target Name="StripWindowsDesktopAppFromRuntimeConfig" AfterTargets="GenerateBuildRuntimeConfigurationFiles">
|
|
<PropertyGroup>
|
|
<_RuntimeConfigPath>$(OutDir)$(AssemblyName).runtimeconfig.json</_RuntimeConfigPath>
|
|
</PropertyGroup>
|
|
<PropertyGroup Condition="Exists('$(_RuntimeConfigPath)')">
|
|
<_RuntimeConfigContent>$([System.IO.File]::ReadAllText('$(_RuntimeConfigPath)'))</_RuntimeConfigContent>
|
|
<_PatchedContent>$([System.Text.RegularExpressions.Regex]::Replace($(_RuntimeConfigContent), ',\s*\{\s*"name":\s*"Microsoft\.WindowsDesktop\.App"[^\}]*\}', ''))</_PatchedContent>
|
|
</PropertyGroup>
|
|
<WriteLinesToFile Condition="Exists('$(_RuntimeConfigPath)') and '$(_RuntimeConfigContent)' != '$(_PatchedContent)'"
|
|
File="$(_RuntimeConfigPath)"
|
|
Lines="$(_PatchedContent)"
|
|
Overwrite="true"/>
|
|
<Message Condition="Exists('$(_RuntimeConfigPath)') and '$(_RuntimeConfigContent)' != '$(_PatchedContent)'"
|
|
Text="Stripped Microsoft.WindowsDesktop.App from $(_RuntimeConfigPath)"
|
|
Importance="high"/>
|
|
</Target>
|
|
|
|
</Project>
|