# Windows desktop build under Wine The PR workflow uses the existing `ubuntu-latest` Gitea runner with pinned Wine 11 and a matching Windows .NET SDK. It builds both the application and test project for `net10.0-windows10.0.19041.0`, then discovers and executes that actual Windows test target through the Windows host. The desktop target retains WPF, `WinExe`, x64, and the Windows recording, hotkey, Outlook, screenshot, tray, and notification implementations. The separate portable job explicitly selects `net10.0`; a Windows host or `win-x64` RID alone does not compile Windows-only tests. ## Observed failures On 2026-10-03, run 4154 at commit `05e23857ddf9e6990b76660e2ef5c1b429bfe66b` used Wine 11 and successfully imported and read back all 372 unique thumbprints from the Microsoft SDK's code-signing and timestamp trust bundles. The Windows SDK targeting-pack diagnostic succeeded, and the Windows desktop restore completed. NuGet signature verification was not disabled. See [the trust helper documentation](wine-sdk-trust.md). The desktop build then failed in `WinAppSdkExpandPriContent` from `Microsoft.Windows.SDK.BuildTools.MSIX` 1.7.20250829.1. MakePRI reported `PRI175: 0x80004001 - Dump`, `MakePri failed with error: Not implemented`, and `PRI222`. The following `Root element is missing` exception came from loading the missing dump output; it was a secondary failure. These logs establish a MakePRI compatibility failure under Wine, but do not identify the particular unimplemented Wine API. ## Dependency correction The resolved Windows graph was: ```text H.NotifyIcon.Uno.WinUI 2.4.1 -> H.NotifyIcon 2.4.1 -> Microsoft.WindowsAppSDK 1.8.251106002 -> Microsoft.WindowsAppSDK.Base 1.8.250831001 -> Microsoft.Windows.SDK.BuildTools.MSIX 1.7.20250829.1 ``` `UnoTaskbarIconService.Windows.cs` uses `H.NotifyIcon.Core.TrayIconWithContextMenu`, `PopupMenu`, `PopupMenuItem`, `PopupMenuSeparator`, and `PopupSubMenu`. These types come from the already-selected `H.NotifyIcon` 2.4.1 assembly. The application does not use the wrapper's WinUI/Uno XAML controls. The Windows package reference therefore selects `H.NotifyIcon` 2.4.1 directly. This keeps the same core assembly and tray APIs while removing the unused WinUI wrapper and its Windows App SDK graph. `CommunityToolkit.WinUI.Notifications` 7.1.2 remains available for toast notifications and does not introduce Windows App SDK in the selected Windows target. The package author's [core-package documentation](https://www.nuget.org/packages/H.NotifyIcon/2.4.1) supports using `H.NotifyIcon` directly, including in console applications. Its `net10.0` dependency group contains `H.GeneratedIcons.System.Drawing` 2.4.1. The [wrapper package](https://www.nuget.org/packages/H.NotifyIcon.Uno.WinUI/2.4.1) adds Windows App SDK for its Windows target. PRI expansion discovers referenced asset files that are absent from normal project outputs and adds them to copy-local output. Disabling that target would risk losing real WinUI resource payloads. This correction removes an unused application dependency instead of disabling PRI generation/expansion, creating a dummy PRI file, suppressing signature checks, or changing the desktop target. ## Qualification and remaining CI evidence Local qualification on 2026-10-03 used the existing `mcr.microsoft.com/dotnet/sdk:10.0-noble` container image with SDK 10.0.401. The existing NuGet package cache was a read-only fallback; new package/cache writes went to a separate temporary directory. This command inside the container compiled the complete Windows desktop target: ```sh dotnet build MeetingAssistant/MeetingAssistant.csproj \ -c Release -f net10.0-windows10.0.19041.0 -r win-x64 \ -p:EnableWindowsTargeting=true -p:RestoreFallbackFolders=/host-nuget --nologo ``` The command returned zero with `Build succeeded`, zero errors, and four existing NAudio deprecation warnings. The produced runtime configuration retains `Microsoft.WindowsDesktop.App` alongside the .NET and ASP.NET frameworks. The regenerated assets graph contains `H.NotifyIcon/2.4.1`, no `Microsoft.WindowsAppSDK*` packages, and no `Microsoft.Windows.SDK.BuildTools.MSIX`; generated package imports contain no Windows App SDK or MakePRI entry. The output `H.NotifyIcon.dll` is byte-identical to the previously selected cached core assembly, with SHA-256 `0027e443a6121af8fb616c0200d3c63bf4abb72e3c548e119fee1eae321a8368`. No application source or target suppression was required. This Linux cross-build does not establish that Windows `dotnet.exe` succeeds under Wine. Completion requires a new Gitea run at the tested revision: successful full Windows desktop and test builds under Wine, named Windows discovery, actual assertion execution with a fresh `artifacts/tests/windows/windows.trx`, and a passing evidence verifier. The workflow removes the previous application DLL/TRX at the expected paths and requires nonempty replacements. All five existing Outlook cases and the Windows-only environment/glyph checks must pass; native macOS tests report their explicit platform skip outside macOS. Windows-target test execution does not establish real Outlook COM, hardware or tray/UI operation. After the workflow installs the Windows SDK and provisions its Wine trust store, its validation commands use the Windows TFM throughout: ```sh set -euo pipefail mkdir -p artifacts/tests/windows "${WINE_BIN}" "${WIN_DOTNET_DIR}/dotnet.exe" restore MeetingAssistant.Tests/MeetingAssistant.Tests.csproj \ -p:TargetFramework=net10.0-windows10.0.19041.0 -p:EnableWindowsTargeting=true -r win-x64 "${WINE_BIN}" "${WIN_DOTNET_DIR}/dotnet.exe" build MeetingAssistant/MeetingAssistant.csproj \ -c Release -f net10.0-windows10.0.19041.0 -r win-x64 -p:EnableWindowsTargeting=true "${WINE_BIN}" "${WIN_DOTNET_DIR}/dotnet.exe" build MeetingAssistant.Tests/MeetingAssistant.Tests.csproj \ -c Release -f net10.0-windows10.0.19041.0 -r win-x64 --no-restore -p:EnableWindowsTargeting=true "${WINE_BIN}" "${WIN_DOTNET_DIR}/dotnet.exe" test MeetingAssistant.Tests/MeetingAssistant.Tests.csproj \ -c Release -f net10.0-windows10.0.19041.0 -r win-x64 --no-build --list-tests \ > artifacts/tests/windows/discovery.txt rm -f artifacts/tests/windows/windows.trx "${WINE_BIN}" "${WIN_DOTNET_DIR}/dotnet.exe" test MeetingAssistant.Tests/MeetingAssistant.Tests.csproj \ -c Release -f net10.0-windows10.0.19041.0 -r win-x64 --no-build \ --logger 'trx;LogFileName=windows.trx' --results-directory artifacts/tests/windows dotnet run tools/VerifyPlatformTests.cs -- windows \ artifacts/tests/windows/discovery.txt artifacts/tests/windows/windows.trx ``` The checked-in workflow additionally records the commit, both SDK identities, Wine version, trust import/readback and targeting-pack diagnostics, plus separate build, discovery, execution and verification logs. It uploads available Windows evidence even after a failed step; the portable job retains its own evidence separately. See [platform test verification](platform-test-verification.md) for native Windows/portable commands and acceptance limits. No required PRI/resource target is disabled.