Store-Fallen #4: .NET Trimming hat WinUI 3-Bindungen weggeschnitten
2026-05-31
Tags: Windows · Microsoft Store · Store-Fallen
Dieses Problem ist mir schon sehr früh begegnet. Beim Schreiben der Store-Fallen-Serie bin ich in meinen E-Mails auf eine alte Ablehnungsnachricht gestoßen — ich hoffe, dieser Beitrag dient als Referenz für Entwickler, die neu im WinUI 3 / .NET-Veröffentlichungsprozess sind.
Was passiert ist
Meine WinUI 3-App wurde zur Microsoft Store-Zertifizierung eingereicht. Der Zertifizierungsbericht kam zurück:
Status: Attention needed
10.1.2.10 Functionality
Unusable Feature: "Download to local cache", "Open File" - The product fails to download copied items to local cache and "Open File" button in the product is not usable
Moment — ich hatte das lokal getestet, und sowohl „Download to local cache" als auch „Open File" funktionierten einwandfrei. Warum funktionierte es auf dem Testgerät von Microsoft nicht?
Fehlersuche
Der verdächtigste Unterschied: Ich hatte lokal einen Debug-Build verwendet, während der Store-Einreichung ein Release-Build eingereicht wurde. Bei der Überprüfung der .csproj-Datei fiel ein entscheidender Unterschied zwischen der Debug- und Release-Konfiguration auf:
<!-- Debug -->
<PublishTrimmed>False</PublishTrimmed>
<!-- Release -->
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>Der Release-Build hatte .NET Trimming aktiviert.
Was ist .NET Trimming
.NET Trimming ist eine Optimierungsfunktion des .NET SDK. Beim Veröffentlichen der App führt der Trimmer eine statische Analyse durch, um Assemblys, Typen und Methoden zu identifizieren, die im Code nie direkt referenziert werden, und entfernt sie dann, um die App-Größe zu reduzieren.
Das Problem: Der Trimmer sieht nur statische Referenzen. Wenn der Code zur Laufzeit über Reflexion auf einen Typ zugreift, aber zur Kompilierzeit keine statische Referenz darauf existiert, hält der Trimmer den Typ für „unbenutzt" und schneidet ihn ab.
Warum WinUI 3 besonders anfällig ist
WinUI 3 und die zugrunde liegende WinRT-Interop-Schicht sind stark auf Reflektion und dynamische Funktionen angewiesen. Traditionelle {Binding}-Ausdrücke, Wertkonverter und WinRT-Interop-Metadatenreflektion erzeugen alle Laufzeitaufrufe, die die statische Analyse des Trimmers nicht verfolgen kann. Wenn der Trimmer die Datenmodelle, Commands, Konverter und andere Typen, die für Bindungen benötigt werden, als „unbenutzt" entfernt, können die Bindungen zur Laufzeit ihre Ziele nicht finden — Schaltflächen funktionieren nicht, Textaktualisierungen bleiben aus. Kein Fehler, kein Absturz, es funktioniert einfach nicht.
Lösung
Der einfachste Weg: Trimming in der .csproj deaktivieren:
- <PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
+ <PublishTrimmed>False</PublishTrimmed>Erneut verpacken und einreichen — die Zertifizierung wurde bestanden.
Wenn Trimming zur Reduzierung der Paketgröße benötigt wird, kann es auch kompatibel gemacht werden:
- Die Attribute
[DynamicDependency]oder[DynamicallyAccessedMembers]auf den benötigten Typen anbringen, um den Trimmer anzuweisen, diese beizubehalten <TrimmerRootAssembly>in der.csprojkonfigurieren, um eine gesamte Assembly beizubehalten
Für die meisten WinUI 3-Apps ist es jedoch die unkomplizierteste Wahl, Trimming einfach zu deaktivieren.
Fazit
- .NET Trimming entfernt Code, den es für „unbenutzt" hält, kann aber Reflexionsaufrufe nicht erkennen
- WinUI 3-Datenbindungen nutzen Reflexion und werden daher leicht versehentlich abgeschnitten
- Wenn eine WinUI 3-App bei der Store-Zertifizierung „nicht verwendbare Funktionen" aufweist, aber lokal einwandfrei funktioniert, sollte als Erstes Trimming untersucht werden
- Debug-Builds verwenden standardmäßig kein Trimming, Release-Builds können es aktivieren — vor der Store-Einreichung unbedingt den Release/Publish-Build testen
- Demnächst folgen wir mit einem Artikel mit Tipps zum Testen vor der Store-Einreichung — bleiben Sie dran
Teil der Store-Fallen-Serie.