08. Windows App Certification Kit

Date: 2026-08-09 Verdict: Overall WARNING, which does not block certification. 22 of 24 tests pass. One optional test fails and one non-optional test warns, and neither is what it looks like at first reading. No code changed as a result.

Report 07 left this as the last untested link in the chain. The kit is not part of the Microsoft.Windows.SDK.BuildTools NuGet package used for the rest of the packaging, so it needed the real Windows SDK installer, run with /features OptionId.WindowsSoftwareLogoToolkit so that nothing else from the SDK was installed.


Environment

Kit version 10.0.26100.1
OS Windows 11 Pro, build 26200
Package under test the signed local test build, QTSTest_1.1.0.0_x64
App type detected Centennial, which is correct for a packaged Win32 desktop app

The submission package was not the one tested, and could not be. The kit installs the package itself in order to drive it, so it needs one that is signed by a trusted certificate. The submission build is unsigned by design because the Store signs it. The two are produced from the same tree by the same script and differ only in the three Partner Center identity values, none of which any of these tests inspect for content.

The test certificate was trusted for the duration of the run and removed afterwards, along with the installed package. Both verified back to zero.


Result

OVERALL_RESULT : WARNING
24 tests run   : 22 PASS, 1 FAIL, 1 WARNING

The single FAIL does not make the overall result a failure because that test carries OPTIONAL="TRUE". That is the kit's own classification, not an interpretation applied here.

Passing, and worth naming because several are the things this project has spent reports on: App manifest, Package sanity, Banned file analyzer, Private code signing, Registry checks, Special use capabilities, Debug configuration, Platform appropriate files, Branding, App resources.


1. Blocked executables, FAIL, optional

The kit scans every binary in the package for imports and string literals associated with launching processes. It found them, and every one is in the Python and Tcl runtime rather than in this application.

Representative findings:

QuickTrueStretch.exe        kernel32.dll!CreateProcessW
_internal\python312.dll     kernel32.dll!CreateProcessW, shell32.dll!ShellExecuteW
_internal\tcl86t.dll        kernel32.dll!CreateProcessW
python312.dll               blocked executable reference to "cmd"
tcl86t.dll                  blocked executable reference to "cmd.exe", "reg"
ucrtbase.dll                blocked executable reference to "cmd.exe"
init.tcl, button.tcl, ...   blocked executable reference to "cmd"

This is a static scan of imports and strings, not an observation of behaviour. Three things about it:

The reference in QuickTrueStretch.exe is the PyInstaller bootloader, which is the same bootloader every PyInstaller application ships. Nothing in this project's source reaches it.

The .tcl hits are almost certainly false in the ordinary sense. cmd is a conventional variable and procedure name throughout Tk's own script library, and button.tcl matching on the string cmd says nothing about launching a shell.

The invariant in CLAUDE.md is about the source, and it still holds. subprocess is not imported, and it is one of the 49 modules excluded in QuickTrueStretch.spec, so the Python module is not even present in the build. What the scan is finding is that the native CPython and Tcl DLLs have CreateProcessW in their import tables, which is true of those runtimes everywhere and is not something an application built on them can remove.

The behavioural answer is already on record. Report 05 sampled a driven session of the packaged one-directory build 83 times and recorded zero child processes. A static import is a capability, a spawned process is an event, and the audits measure the event.

No change made. There is no version of this application, written in Python and drawn with Tk, that passes this scan. The honest position is to know why it fails and be able to say so, which is what this section is for.

2. DPIAwarenessValidation, WARNING, not optional

File QuickTrueStretch.exe neither has PerMonitorV2 manifested in the manifest
nor calls into DPI Awareness APIs for ex: user32!SetProcessDpiAwarenessContext
or user32!SetThreadDpiAwarenessContext.

The app QTSTest_1.1.0.0_x64__tfk9jy4yd9n6a is not DPI Aware.

The second sentence is wrong, and the first sentence explains why the kit believes it.

enable_dpi_awareness() calls SetProcessDpiAwarenessContext with DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, before any window exists, with a documented fallback chain behind it. It does so through ctypes, which resolves the symbol at runtime. There is therefore no static import of user32!SetProcessDpiAwarenessContext in the PE import table for the kit to find, and the embedded manifest does not declare PerMonitorV2 either. The kit looks in exactly those two places and concludes, reasonably from what it can see, that the app is unaware.

It is aware. Report 06 rendered the interface on a display actually set to 125 and 150 percent and measured the window at 426, 531 and 636 physical pixels across the three scales, against 1.25 and 1.5 expected. A DPI unaware process would have been bitmap stretched by Windows and would have measured 426 at all three.

No change made, deliberately, and this is a judgement rather than an oversight. Declaring PerMonitorV2 in the embedded manifest as well would clear the warning and would apply awareness marginally earlier than the first line of Python. It would also mean editing the manifest PyInstaller embeds, in the one area of this application that has cost the most defects, and CLAUDE.md requires a re-measure at all three scales after any change there. A warning that is factually wrong about a property verified visually on real hardware is not worth that risk before a first submission.

It is recorded in TODOS.md so that nobody rediscovers it mid-certification and treats it as a surprise.


What this pass did not test

  1. The submission package itself. See the note under Environment. Unsigned packages cannot be installed and the kit installs what it tests.
  2. Anything about the three identity values. They are the only difference between the tested package and the one that gets uploaded, and no test here reads them.
  3. Certification itself. The kit is a local approximation of the Store's automated checks. It is not the Store, and passing it is not a guarantee.
  4. The upgrade path. Only a clean install was exercised, here and in report 07.