Declare Microsoft.VCLibs.140.00.UWPDesktop as a required x64 framework dependency, source its exact MinVersion from the selected VCLibs Extension SDK’s SDKManifest.xml, and exclude the five private runtime DLLs from the final PyInstaller payload unless Microsoft confirms a separate app-local deployment design for this packaged scenario.
Supported package configuration
For a Desktop Bridge application dependent on the dynamic VC++ runtime, Microsoft’s documented contract is to reference the corresponding Desktop C++ Runtime framework package rather than merely redistribute the Visual Studio/VCRedist DLLs. The documented v14 identity and publisher match those in the question.^1^
Add this under the existing manifest <Dependencies> element:
<PackageDependency
Name="Microsoft.VCLibs.140.00.UWPDesktop"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
MinVersion="REPLACE_FROM_SDKMANIFEST" />
MinVersion is the minimum framework package version, not the Windows minimum version, DLL file version, or compiler version. At deployment, Windows requires a dependency package whose version is equal to or greater than that value.^2^
Determine the value as follows:
- Establish the MSVC toolset used to build every native input in the frozen 791-file revision:
- CPython and its native modules;
- PyInstaller
run.exeandrunw.exe; - Qt/PySide6 and Shiboken6 binaries;
- every additional
.pydand native DLL.
- Install/select the matching supported VCLibs Desktop Extension SDK.
- Open its
SDKManifest.xml. - Copy the
Name,Publisher, andMinVersionfromFrameworkIdentity-RetailintoAppxManifest.xml. This is Microsoft’s documented procedure; the example values such as14.0.24217.0or14.0.27323.0are examples, not a basis for selecting the current package’s minimum.^3^ - Build and test against that minimum and newer compatible framework versions.
The general VC runtime rule is that the deployed v14 runtime must be the same version as or newer than the newest MSVC toolset used to build any loaded component. Visual Studio 2015–2026 use the compatible v14 family, but an older runtime is unsupported for a component built with a newer toolset.^4^
The cited documentation does not provide a universal table mapping every Microsoft.VCLibs.140.00.UWPDesktop package version to each contained DLL file version and every supported MSVC toolset. Therefore, neither 14.0.33321.0 nor the installed 14.0.33728.0 can be selected solely from its numeric similarity to a toolset or DLL. Inspect the actual Extension SDK package and SDKManifest.xml; obtain build-toolset provenance from each binary supplier where it is not recorded.
Framework versus private DLLs
For this Desktop Bridge configuration, remove these private candidates from the final package after confirming the framework contains the complete imported set:
-
msvcp140.dll -
msvcp140_1.dll -
msvcp140_2.dll -
vcruntime140.dll -
vcruntime140_1.dll
Do not intentionally mix private and framework copies under the assumption that the framework will win. For packaged desktop processes, name-based lookup checks the process package graph before the executable directory, but loaded-module reuse, Known DLLs, explicit paths, SxS redirection, and altered search modes can change the observed binding.^5^
Microsoft’s general redistribution guidance permits local deployment in ordinary VC++ deployment scenarios, while discouraging it because the application becomes responsible for servicing.^4^ However, the more specific Desktop Bridge guidance says applications in that container must specify the Desktop framework and must not simply use Visual Studio/VCRedist runtime copies.^1^ That case-specific rule should govern this MSIX.
Main and Helper processes
The manifest dependency is package-level, not executable-specific. A packaged process receives a graph containing its main package and manifest-declared framework dependencies at process creation.^6^ This makes the runtime available before Python starts, so runtime hooks and AddDllDirectory calls are neither required nor early enough to establish the bootloader’s statically imported VC runtime.
Apply the same validation independently to Main and Helper:
- Launch each through its intended production path.
- Confirm that each process has package identity. In Task Manager, enable Details → Select columns → Package name, or call
GetCurrentPackageFullName;ERROR_INSUFFICIENT_BUFFERindicates identity andAPPMODEL_ERROR_NO_PACKAGEindicates none.^7^ - Query each process’s graph with
GetCurrentPackageInfo, requesting the applicable static framework entries, and verify the resolved x64Microsoft.VCLibs.140.00.UWPDesktopfull name/version.^8^ - If Helper reports no package identity or its graph lacks VCLibs, its actual launch arrangement has not produced the required packaged runtime context. A successful historical direct launch does not establish that contract.
The available documentation does not state that every arbitrary helper-launch mechanism necessarily preserves the parent’s identity or graph. Validate the exact packaged activation/launch route rather than inferring inheritance from the parent process.
Binding verification
Use separate evidence for graph membership and loader binding:
- Graph:
GetCurrentPackageInfoestablishes which packages are available to that process; it does not prove which DLL won lookup. - Loaded provider: Run
listdlls -v <PID>for each process. ListDLLs reports loaded DLL paths and full version information; use-uas an additional unsigned-module check.^9^ - Live/short-lived loads: Capture Process Monitor events filtered to Main/Helper process names and the five DLL names. Process Monitor records process, file-system, and DLL activity in real time.^10^
- Earliest loader decisions: Before launching either executable, enable per-image loader snaps:
gflags /i Main.exe +sls
gflags /i Helper.exe +sls
Attach/capture with the Windows debugger. Loader snaps record DLL loading and unloading for each configured image, including failures occurring before Python initialization.^11^
After testing, remove the diagnostic setting:
gflags /i Main.exe -sls
gflags /i Helper.exe -sls
For every one of the five names, record: importing module, attempted paths, selected full path, file version/signature, process package identity, and resolved framework package full name. A path under the resolved VCLibs framework package demonstrates framework binding; an application-directory or _internal path demonstrates private binding; a System32 path demonstrates system fallback. Repeat on a clean x64 VM with only the declared dependency installed, rather than relying on the development machine’s existing x86/x64 registrations.
References
- C++ Runtime framework packages for Desktop Bridge
- PackageDependency
- Prepare to package a desktop application
- Determine which DLLs to redistribute
- Dynamic-link library search order
- MSIX framework packages and dynamic dependencies
- Detect package identity and runtime context
- GetCurrentPackageInfo function (appmodel.h)
- ListDLLs v3.21
- Sysinternals Process Utilities
- Show loader snaps