-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unpackaged framework-dependent app crashes if fusion manifest not present/embedded #2634
Comments
That's surprising - I thought I'd built apps using WinAppSDK/fwk-dependent and no Fusion manifest. Will investigate.
Checking for Fusion manifest is expected. Failing when not found or embedded (even if it has no RegFreeWinRT info) is not expected. The WinRT activation+metadata lookup hunt sequence1,2,3 with WinAppSDK is...
When the Bootstrapper fires in an app using WinAppSDK framework-dependent it should find WinAppSDK types via 1 and OS types via 3 (e.g. PackageManager). The latter case will cause lookups to walk through the Fusion manifest (if any) but it should be fine if the executable has none (or an embedded one w/o any RegFree info).
In the simple case. It could have more e.g. if a LolzCatzVidz project uses WinAppSDK framework-dependent and a AwesomeSauceVideoPlaybackWidget WinRT object from another library in a self-contained way. 1 WinRT types in the 2 Windows (without WinAppSDK) has a slightly different ordering: 1=PackageGraph, 2=RegFreeWinRT (19H1+). 3 Langauge projections can supplment the hunt sequence e.g. C++/WinRT and C#/WinRT add a step |
Given that the package graph satisfied the hunt, I don't think WAS should have ever attempted to look for URFW / OS metadata right? Or are you searching all sources for the best candidate? (If so, would be great to see that debug spew added in a future release I think.) |
For what type? And used how?
isn't an unusual "use X if available" recipe, just like
It depends on what ACID is being looked for when this went sideways.
Not COM/WinRT. That's purely "Find X, and 1st match wins" model (same as it's been for decades) Something seems fishy but I can't put my finger on it. Yet. I need to do some poking and prodding... |
TL;DR UndockedRegFreeWinRT has a few discrepancies from Windows' RegFreeWinRT behavior. Putting together some tests to repro and then verify changes. UndockedRegFreeWinRT (URFW) will load an Fusion manifest embedded for an exe or dll or a file if not exe|dll HRESULT LoadManifestFromPath(std::wstring path)
{
if (path.size() < 4)
{
return COR_E_ARGUMENT;
}
std::wstring ext(path.substr(path.size() - 4, path.size()));
if ((CompareStringOrdinal(ext.c_str(), -1, L".exe", -1, TRUE) == CSTR_EQUAL) ||
(CompareStringOrdinal(ext.c_str(), -1, L".dll", -1, TRUE) == CSTR_EQUAL))
{
return LoadFromEmbeddedManifest(path.c_str());
}
else
{
return LoadFromSxSManifest(path.c_str());
}
} That's not how Windows does it. Windows will load an embedded manifest if exists, and then from a file (as an override). Supposed to give devs the easy 'embed when built' and admins the ability to 'provide via file and override the embedded (if any)'. And that's only called once via So And even if we have an embedded manifest we're not looking for a file manifest (as an admin override). Problem #2.
Lookup of the embedded manifest resource is
1=CREATEPROCESS_MANIFEST_RESOURCE_ID == exe 2=ISOLATIONAWARE_MANIFEST_RESOURCE_ID == dll 3=ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID Remarks mention "This is never used by the loader." and it's not otherwise interesting to URFW so we can ignore it. We're always checking id 1+2. We should only check 1 for exe and 2 for dl. Problem #4. Whipping up a test suite for the various permutations and then fixes. |
Oops! Sorry I missed this question earlier
UndockedRegFreeWinRT resolves Fusion + MSIX manifests at different times - DLL load vs 1st-use. Fusion manifest resolution occurs in Microsoft.WindowsAppRuntime.dll's This differs from URFW's package graph support. That can change dynamically over the life of the process so that's resolved on 1st use as needed (i.e. just-in-time). As that's based on appxmanifest.xml and packages should be immutable once installed the manifest itself wouldn't change, we simply don't know which packages may be needed until later when we use WinRT activation (or metadata) APIs. We walk the package graph looking for answers and if a package's manifest hasn't been loaded yet it's loaded and cached for all successive uses of that package's manifest.
Small correction. Technically we use URFW to resolve Fusion+MSIX manifested WinRT metadata. URFW is the code altering WinRT's activation+metadata lookup to also use our Fusion+MSIX data. |
Very happy to see you tracked it down and we're going to see URFW support loose fusion manifests again. That will make things a lot easier for Rust where there's no easy access to MT. |
According to #2597, issue was fixed in 1.5.240205001-preview1 |
Describe the bug
In scenarios where the fusion manifest is not embedded into the output executable, an app bootstrapping with Windows App SDK will fail to start. This appears to have regressed since 1.0.0.
Repro project: repro.zip
Steps to reproduce the bug
<EmbedManifest>false</EmbedManifest>
with<EmbedManifest>true</EmbedManifest>
.Expected behavior
App to start correctly regardless of fusion manifest presence.
NuGet package version
1.1.1 ❌ Broken
1.1.0 ❌ Broken
1.0.4 ❌ Broken
1.0.3 ❌ Broken
1.0.2 ❌ Broken
1.0.1 ❌ Broken
1.0.0 ✔️ Works
Packaging type
Unpackaged
Windows version
Insider Build (xxxxx)
IDE
Visual Studio 2022
Additional context
Impacted Rust bindings, which does not use fusion manifests.
It appears the bootstrapping component is attempting to locate reg-free WinRT information. In non-framework-dependent apps, that is expected. In framework-dependent apps it is not. The fusion manifest in these scenarios will have very little aside from optional common controls/DPI flags.
Output window
The text was updated successfully, but these errors were encountered: