Worked example: full-trust desktop receiver
This example records decisions and failures from a successful Microsoft Store submission. It is prior art, not a template to copy without checking the new application.
Product and package
- Product: Mirror Me Phone Display
- Store product ID, package identity name, publisher ID, publisher display
name, and package family name: copied exactly from Partner Center
Product identity. They are specific to one developer account, so they
are not repeated here. The publisher ID has the form
CN=<GUID>, and the package family name is the identity name, an underscore, and a 13-character publisher hash. - Application version:
0.2.4 - MSIX version:
1.2.4.0 - Architecture: x64
- Minimum Windows version:
10.0.22000.0
The application version was below 1.0, but MSIX does not allow a zero first
component. The build mapped 0.2.4 to 1.2.4.0. The fourth component remained
zero for Store use.
Package model
The application was a Wails and Win32 desktop app with:
packagedClassicAppmediumILrunFullTrust- A packaged
windows.startupTask - A same-executable
--receiver-workermode - Native DNS-SD, Media Foundation, GDI, and WASAPI integration
- No elevation
- No service
- No driver
- No system-wide settings
- No cloud backend
The Store MSIX was intentionally unsigned. Microsoft signs Store packages after certification.
First package rejection
The initial upload used the correct application visual name but retained:
<Properties>
<DisplayName>MirrorMe</DisplayName>
</Properties>MirrorMe was not a reserved Store name. Partner Center rejected the package.
The fix was to parameterize every display-name surface and rebuild with:
<Properties>
<DisplayName>Mirror Me Phone Display</DisplayName>
</Properties>The application visual display name and StartupTask display name were changed to the same reserved name.
Lesson: validate Package/Properties/DisplayName, not only
uap:VisualElements/@DisplayName.
Name and trademark decision
Names containing AirPlay were considered, but Apple naming guidance made a
protocol trademark in the product name undesirable without permission.
The reserved name avoided the trademark. Compatibility language appeared in the listing instead:
Compatible with screen mirroring from AirPlay-enabled devices.
The listing also stated:
AirPlay is a trademark of Apple Inc. This app is not affiliated with or endorsed by Apple.
Lesson: use protocol compatibility language in the description when the trademark should not appear in the product name.
Partner Center configuration
Pricing and availability:
- Free
- All current and future markets
- Public and discoverable
- Publish automatically after certification
Properties:
- Primary category: Utilities + tools
- Secondary category: Photo + video
- Personal information use: Yes
- Privacy, website, and support URLs supplied
- Unsupported capability and accessibility claims left disabled
Age rating:
- App type: All Other App Types
- Online content: Yes, because the app displays live content from a paired phone
- Seller-curated mature content: No
- User communication: No
- Purchases and rewards: No
- Precise location sharing: No
- Browser behavior: No
- Result: all-ages ratings, including ESRB Everyone and Microsoft 3+
Lesson: displaying external live content can count as online content without making the app a browser, communications service, or mature-content catalog.
Full-trust explanation
The explanation covered:
- The Wails and native Win32 desktop architecture
- The same-executable receiver worker
- DNS-SD discovery
- Media Foundation, GDI, and WASAPI
- Packaged startup-task behavior
- Tray and lifecycle integration
- No elevation, driver, service, system-wide setting, or cloud backend
Lesson: name the concrete native behavior and explicitly rule out higher-risk system integration that the app does not use.
Store listing
The listing included:
- Concrete connection steps
- Same-network requirement
- Pairing PIN behavior
- Local privacy behavior
- Firewall and multicast requirements
- Protected and DRM content limitations
- Apple trademark attribution
- GPL v3-or-later and corresponding-source information
- Genuine light and dark application screenshots
Two screenshots were resized to a Store-recommended width before upload.
Screenshot upload quirk
Partner Center created a new hidden file input after every screenshot upload.
Uploading both screenshots through input index 0 targeted or replaced the
first screenshot. The second screenshot had to use the next input index.
Lesson: recount input[type="file"] after every upload and use the newly
created input for the next image.
Certification instructions
The testing notes explained:
- Same-network setup
- iPhone Control Center and Screen Mirroring connection flow
- PIN pairing
- Full-screen and tray behavior
- Packaged StartupTask behavior
- Same-executable worker architecture
- Firewall and multicast requirements
- Protected-content limitations
- Trademark and non-affiliation language
No credentials were required.
WACK
The WACK command returned exit code zero, but the requested XML report was not found. The real report was generated as:
%LOCALAPPDATA%\Microsoft\AppCertKit\MirrorMe-WACK-report.htmThe HTML report said:
Overall result: PASSEDRequired and optional tests passed.
Lesson: locate and parse the generated report. Do not trust the process exit code by itself.
A later submission of another full-trust desktop app used WACK 10.0.26100.8249:
- A report path ending in
.htmfailed with exit code -1 andThe report output file path should point to a XML file. - A path ending in
.xmlworked. WACK wrote the XML report to that path and an HTML rendering to%LOCALAPPDATA%\Microsoft\AppCertKit\<same base name>.htm, both before it exited. - The XML root element,
REPORT, carriesOVERALL_RESULT,VERSION(the kit version),APP_NAME(the package identity name, not the display name),APP_VERSION,PARTIAL_RUN, andReportGenerationTime. The HTML report shows the same report time, which ties the two files together. OVERALL_RESULTisPASS,FAIL, orWARNING. The HTML report shows these asPASSED,FAILED, andPASSED WITH WARNINGS. The originalinvoke-wack.ps1read only the first word afterOverall result:, so it would have reportedPASSED WITH WARNINGSasPASSED.- The optional
Blocked executablestest failed while the overall result was stillPASS. WACK flagged a reference to the process-launch APIkernel32.dll!CreateProcessWand references to blocked executables such asCmd,powershell, andREGin the main executable, andbashandregin a bundled helper executable. The report says optional tests "are informational only and will not be used to evaluate your app during Microsoft Store onboarding." %LOCALAPPDATA%\Microsoft\AppCertKitalso held about 30 unrelated XML files, such as logs and a task schedule. Only a file whose root element isREPORTis a WACK report.
Lesson: treat the XML report as the source of truth, match its identity name and version to the package, and fall back to the HTML report only when no XML report exists.
Agreement and final submission
Partner Center required:
- App Developer Agreement - Windows Store
- Version 8.11
The exact agreement was presented to the user as a binding legal agreement. After explicit approval, the Windows agreement row was accepted and verified by its acceptance date.
After a reload, every section returned to Complete, the package returned to
Validated, and Submit for certification became enabled.
The user was told that approval would publish the product automatically. After fresh explicit approval, the button was pressed once. Partner Center changed to:
In certification
Submission
Pre-processing
Certification
PublishingAn optional feedback survey appeared after submission and was left untouched.
Remaining risks at submission time
- Broad physical-device and network testing was incomplete.
- A rare quit hang had not been conclusively eliminated.
- Legal review of protocol interoperability, trademarks, codec patents, and GPL distribution remained prudent.
runFullTruststill required Microsoft's certification approval.
Lesson: passing package validation and WACK does not erase product, interoperability, legal, or restricted-capability risk.