microsoft / WindowsAppSDK

The Windows App SDK empowers all Windows desktop apps with modern Windows UI, APIs, and platform features, including back-compat support, shipped via NuGet.
https://docs.microsoft.com/windows/apps/windows-app-sdk/
MIT License
3.78k stars 319 forks source link

Windows App Runtime Install fails with 0x80073cff #2469

Open jaimecbernardo opened 2 years ago

jaimecbernardo commented 2 years ago

Describe the bug

We're distributing Windows App Runtime 1.0.3 as part of PowerToys and some users are reporting installation errors.

This specific error: https://github.com/microsoft/PowerToys/issues/18021#issuecomment-1116999749

It states that "To install this application you need either a Windows developer license or a sideloading-enabled system."

All I could found about this was https://github.com/microsoft/WindowsAppSDK/issues/1119 which stated this shouldn't happen for stable releases.

Steps to reproduce the bug

Download Windows App Runtime 1.0.3 installer and run it.

Expected behavior

No response

Screenshots

image

NuGet package version

No response

Packaging type

No response

Windows version

No response

IDE

No response

Additional context

No response

jaimecbernardo commented 2 years ago

It seems users have been able to fix it by enabling side-loading, but that might be blocked on some enterprise enviornments. https://github.com/microsoft/PowerToys/issues/18021#issuecomment-1118380330

I find this weird, since I've been able to install the runtime on machines without sideloading enabled. So, there might be other settings causing this?

DrusTheAxe commented 2 years ago

I find this weird, since I've been able to install the runtime on machines without sideloading enabled.

Depends on the Windows SKU and version. The policy default disallowed sideloading in Windows 8.

The policy default changed on desktop some years back (RS5? @cwruss can confirm the release). So if you're on a recent-ish desktop release the policy default is enabled and sideloading is fine. Unless the policy was changed; administrators can and sometimes do do that.

NOTE: The policy's default was only changed for desktop. Windows Server still has the same old default of disabled. You need to change that to enable sideloading on Server.

There's more info at the microsoft/PowerToys#18021 (comment) thread about this, including how to change it. Key link reproduced here for posterity:

Thumb24 commented 4 hours ago Here you can find the instruction how to activate sideloading: https://www.windowscentral.com/how-enable-windows-10-sideload-apps-outside-store

DominicMaas commented 2 years ago

I thought that sideloading was not a requirement for stable Windows App SDK Runtimes? (as per #1119)

pbargiona commented 2 years ago

Activating "Install apps from any source, including loose files" solved my problem.

image

AdamBraden commented 2 years ago

@pbargiona , curious what do you have for this setting? Settings->Apps->Advanced app Settings

image

riverar commented 2 years ago

Activating "Install apps from any source, including loose files" solved my problem.

This is not ideal to keep on or as a workaround, as it loosens restrictions on symlinks and a few other things IIRC.

pbargiona commented 2 years ago

@pbargiona , curious what do you have for this setting? Settings->Apps->Advanced app Settings

image

@AdamBraden image

Activating "Install apps from any source, including loose files" solved my problem.

This is not ideal to keep on or as a workaround, as it loosens restrictions on symlinks and a few other things IIRC.

Definitely. I disabled this option right after updating from the menu in WinPowerTowys. This seems to be an issue with WinAppSDK 1.0.3. It should not need such configs to work, but it does.

DrusTheAxe commented 2 years ago

FYI the impact of not-Store-signed DDLM packages is a bit larger than anticipated. The Settings workaround (at least toggled temporarily for the install) works but we understand is suboptimal. We're investigating options but it involves a complicated mix of issues (technical and not) so please bear with us.

riverar commented 2 years ago

@DrusTheAxe Still isn't clear what the issue here. I don't need to toggle that on my scratch machines. Or is this specifically a Windows 10 issue?

BenJKuhn commented 2 years ago

Let me see if I can summarize a bit:

The Windows App SDK relies on 2-5 packages at runtime, depending on usage & version. Just looking at 1.0...

The runtime package with all the interesting code is, WindowsAppRuntime.1.0, is store signed and available in the store. This package does not require side-loading. The same is true for the WindowsAppRuntime.Main.1.0 package, which contains services & registrations that can't exist in a framework package (since it's shared between apps). If you're installing an MSIX-packaged app, this is all you need, and you can install even on machines that only allow apps from the store.

There are 3 DDLM (dynamic dependency lifetime manager) packages for each release, one per architecture. These are "main" packages, not framework packages. They're used to bridge from non-packaged apps to the framework package. These packages are regenerated with new package identity for each architecture and servicing release. They exist only to support apps that are not distributed via MSIX (those apps can just reference the App SDK directly). To side-load and run these packages from the installer, they need to be either:

  1. signed for side-loading (e.g. "Microsoft" signing) or ...
  2. "Microsoft Store" signed and come with an OEM preinstall license file.

There are a number of practical considerations that make acquiring new store signing & licenses for these packages problematic, at least for now. We looked at the side-loading policy and since it's been enabled by default on desktop since RS5 (our min target) and the software that depends on by definition isn't coming from the Store, we decided to use the Microsoft signing rather than Microsoft Store signing.

It's clear from the feedback in this thread that this is causing more difficulty for folks than we anticipated, and we're exploring better options to address this issue. Unfortunately, it's not an easy problem. We have some ideas but may take a little while to prototype, build, validate and distribute an appropriate fix.

Ben

pbargiona commented 2 years ago

Let me see if I can summarize a bit:

The Windows App SDK relies on 2-5 packages at runtime, depending on usage & version. Just looking at 1.0...

The runtime package with all the interesting code is, WindowsAppRuntime.1.0, is store signed and available in the store. This package does not require side-loading. The same is true for the WindowsAppRuntime.Main.1.0 package, which contains services & registrations that can't exist in a framework package (since it's shared between apps). If you're installing an MSIX-packaged app, this is all you need, and you can install even on machines that only allow apps from the store.

There are 3 DDLM (dynamic dependency lifetime manager) packages for each release, one per architecture. These are "main" packages, not framework packages. They're used to bridge from non-packaged apps to the framework package. These packages are regenerated with new package identity for each architecture and servicing release. They exist only to support apps that are not distributed via MSIX (those apps can just reference the App SDK directly). To side-load and run these packages from the installer, they need to be either:

  1. signed for side-loading (e.g. "Microsoft" signing) or ...
  2. "Microsoft Store" signed and come with an OEM preinstall license file.

There are a number of practical considerations that make acquiring new store signing & licenses for these packages problematic, at least for now. We looked at the side-loading policy and since it's been enabled by default on desktop since RS5 (our min target) and the software that depends on by definition isn't coming from the Store, we decided to use the Microsoft signing rather than Microsoft Store signing.

It's clear from the feedback in this thread that this is causing more difficulty for folks than we anticipated, and we're exploring better options to address this issue. Unfortunately, it's not an easy problem. We have some ideas but may take a little while to prototype, build, validate and distribute an appropriate fix.

Ben

Quite a clear explanation. I hope I've been able to fully comprehend it.

I encountered the problem that originated this thread while installing PowerToys, whose installer seems to be trying to install from the runtime package (EXE), not the DDLM. I say this based on the following installation fail log:

[3014:3B10][2022-05-04T03:03:51]i301: Applying execute package: WinAppSDK101, action: Install, path: C:\ProgramData\Package Cache\1269BB136655325EF6D66A018269BDAB3921E56B\WindowsAppRuntimeInstall.exe, arguments: '"C:\ProgramData\Package Cache\1269BB136655325EF6D66A018269BDAB3921E56B\WindowsAppRuntimeInstall.exe"'
[3014:3B10][2022-05-04T03:03:56]e000: Error 0x80073cff: Process returned error: 0x80073cff
[3014:3B10][2022-05-04T03:03:56]e000: Error 0x80073cff: Failed to execute EXE package.
[11E4:2748][2022-05-04T03:03:56]e000: Error 0x80073cff: Failed to configure per-machine EXE package.
[11E4:2748][2022-05-04T03:03:56]i319: Applied execute package: WinAppSDK101, result: 0x80073cff, restart: None
[11E4:2748][2022-05-04T03:03:56]e000: Error 0x80073cff: Failed to execute EXE package.
[3014:3B10][2022-05-04T03:03:56]i351: Removing cached package: WinAppSDK101, from path: C:\ProgramData\Package Cache\1269BB136655325EF6D66A018269BDAB3921E56B\
[3014:3B10][2022-05-04T03:03:56]i372: Session end, registration key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{7f0d7424-d132-4aaf-baa9-5d7d436f0feb}, resume: None, restart: None, disable resume: No
[3014:3B10][2022-05-04T03:03:56]i330: Removed bundle dependency provider: {7f0d7424-d132-4aaf-baa9-5d7d436f0feb}
[3014:3B10][2022-05-04T03:03:56]i352: Removing cached bundle: {7f0d7424-d132-4aaf-baa9-5d7d436f0feb}, from path: C:\ProgramData\Package Cache\{7f0d7424-d132-4aaf-baa9-5d7d436f0feb}\
[3014:3B10][2022-05-04T03:03:56]i371: Updating session, registration key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{7f0d7424-d132-4aaf-baa9-5d7d436f0feb}, resume: None, restart initiated: No, disable resume: No
[11E4:2748][2022-05-04T03:03:56]i399: Apply complete, result: 0x80073cff, restart: None, ba requested restart:  No

Can this possibly mean that making the DDLM packages more easily incorporable by developers using WinAppSDK dependencies (such as PowerToys) could prevent the hassles of needing dev privileges to install programs?

BenJKuhn commented 2 years ago

@pbargiona that's correct. The error is coming from the installer trying to register the DDLM package as part of its setup work. Any fix we make for this would remove the requirement for the client machine to enable side-loading of applications.

As things stand now, allowing developer-created apps will also address the issue, but is more permissive than is strictly required.

Ben

riverar commented 2 years ago

PowerToys bundled the runtime installer. I ran the same installer on a fresh box and no unblock was needed. So what's the issue here? (I'm very familiar with WAS/WAR inner workings and would appreciate consideration of that in your response. :smile:)

@DrusTheAxe @BenJKuhn Were you guys actually able to reproduce this?

BenJKuhn commented 2 years ago

The default settings on Windows 10 (RS5+) and Windows 11 will allow the DDLM packages to be installed with no issue.

On Windows 11,

That got me to the error shown here, which is consistent with expectations.

Ben

riverar commented 2 years ago

@BenJKuhn But that's not consistent with the users machine, right? They appear to be on 22000 with defaults, looking at the msi log.

jaimecbernardo commented 2 years ago

It seems like it can be prevented from running with AppLocker as well, due to being an packaged app, perhaps? I'm guessing this one is not sideloaded, or is it: https://github.com/microsoft/PowerToys/issues/18047#issuecomment-1121471673

rcohn commented 2 years ago

Hello -

Regarding this statement above: To side-load and run these packages from the installer, they need to be either: signed for side-loading (e.g. "Microsoft" signing) or ... "Microsoft Store" signed and come with an OEM preinstall license file.

Do I understand that if an app built with WindowsAppRuntime is signed with a PFX cert file (using signtool), then the app does not require sideloading enabled? That sounds like a simple solution around the sideloading question, but I am probably over-simplifying things.

One final point of note based on the following from: https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/stable-channel#version-111 Running the Windows App Runtime installer (WindowsAppRuntimeInstall.exe) requires sideloading to be enabled. See issue 2469 on GitHub for more information.

I was able to install WindowsAppRuntime 1.1.0 on a Win11 system without enabling Developer Mode. According to the above quote, that should not be possible. I'm guessing I could do that because this WindowsAppRuntime installer is signed?

Thanks very much.

DrusTheAxe commented 2 years ago

if an app built with WindowsAppRuntime is signed with a PFX cert file (using signtool), then the app does not require sideloading enabled?

Not quite. It's not merely being signed but with what cert that matters. If you sign your package yourself then it won't be Store-signed (or Windows-signed) since you don't have those private keys to sign packages. You'll be signing your package with an 'other' cert, just like WinAppSDK signs its DDLM packages (or all packages for experimental and preview releases).

As you might guess, how you sign your app's package has no bearing on how WinAppSDK runtime's MSIX packages are signed. If your package is signed with a not-Store (and not-Windows) cert then installing your package faces the same issue as installing WinAppSDK's DDLM packages (which are never Store signed today).

Oversimplistically, you can think of there being 4 possibilities:

  1. Unsigned
  2. Signed with Windows' cert
  3. Signed with Store's cert
  4. Signed by any-other-cert known to the machine's cert store

MSIX packages built as part of Windows are signed with Windows' cert (and only Windows components can be signed with Windows' cert). For example, the Microsoft.Windows.ShellExperienceHost package is part of Windows and signed with the Windows cert. Windows signed packages can always be installed; there is no policy to block this type of signing (it's essentially no different than ntdll.dll and other Windows components).

MSIX packages submitted to the MS Store are signed by the Store with the Store's cert. These can be installed on Windows.

You can use other certs to sign an MSIX package and as long as the cert's known to Windows (i.e. in the machine's certificate store, or chained to a cert in the cert store).

NOTE: This is sometimes referred to as 'side loading' or 'sideloaded packages' which is a bit of a misnomer as 'side loading' is a verb, as in, the act of loading a package via a side channel, path or mechanism (i.e. not directly from Store or Windows). If you submitted a package to the MS Store it'll be Store signed. lf you acquired the Store signed .msix and installed it (e.g. via Add-AppxPackage) then you have literally 'side loaded' the package but it's still a Store signed package. But terminology's been a bit confusingly applied over the years so if you hear 'sideloading' you can assume it means 'signed with not-Store and not-Windows cert'.

"Side loading" isn't the significant issue. What matters is how the package is signed. This is queryable via GetStagedPackageOrigin(), Windows.ApplicationModel.Package.SignatureKind or the Get-AppxPackage powershell cmdlet (look for the SignatureKind property).

There's a policy you can set to allow or block packages signed by 'other' certs. Administrators can (and sometimes do) enable it to prevent installing MSIX packages that aren't signed by the MS Store (or Windows).

That used to be the default value for the policy way back in Win8 - only allow Store-signed packages, unless you altered it in Setting (or admins set a group policy, same diff). Windows desktop (aka client aka Home/Professional/...) changed the default in RS5 from allow=Store to allow=Store-or-Other. But that's just the default; the policy still exists, and admins can disable it if they choose (as some do). In addition, that default was only changed for Windows desktop; Windows Server's default hasn't changed, it's still "allow=Store" so packages signed by other certs will fail to install (unless the policy is altered).

NOTE: The policy is actually a 3 state: allow = Store or Store-and-Other or Store-and-Other-and-Developer. Settings in Win8 shows 3 radio buttons to choose from. Settings changed in RS5 along with the policy, it's now controlled by the "Developer Mode" option. If you set that On that you essentially set the policy to allow = Store-and-Other-and-Developer, and if it's Off you're effectively setting allow = Store-and-Other by default, or Store (only) if the policy has been set. Or at least, that's the user experience on desktop; I haven't seen Settings on Server in a while so I don't know how that's visualized. But that's just the UI; it doesn't change the fact the built-in default for the policy differs on desktop vs server.

WinAppSDK Store signs its Framework, Main and Singleton packages for Stable releases.

One final point of note based on the following from: https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/stable-channel#version-111 . Running the Windows App Runtime installer (WindowsAppRuntimeInstall.exe) requires sideloading to be enabled. See https://github.com/microsoft/WindowsAppSDK/issues/2469 on GitHub for more information.

Not quite. The installer is effectively a big wrapper over multiple calls to pkgmgr.AddPackageAsync() for WinAppSDK's MSIX packages -- Framework, Main, Singleton and DDLM. WinAppSDK Stable releases Store-sign the former and 'Other' sign the DDLM packages. The installer isn't special. What matters is the act of installing the DDLM packages which are not Store-signed runs into this "does the machine allow 'Other' signed packages to be installed?" The default answer is Yes on desktop and No on server, unless an admin has changed to policy (or Setting's "Developer Mode" option is On).

You can get the WinAppSDK runtime's MSIX packages by downloading the WinAppSDK redistributable or grab them from inside the WinAppSDK nuget (they also happen to be embedded inside the installer's exe, but all the same thing). How you get the MSIX packages doesn't matter, only how they're signed.

I was able to install WindowsAppRuntime 1.1.0 on a Win11 system without enabling Developer Mode

I'd guess this was a Windows desktop system (not Windows Server) and no admin changed the policy from the default (allow=Store-and-Other) to only allow=Store-signed packages.

"Enable Developer Mode" is a workaround for those using systems the admin has set the policy to disallow 'Other' signed packages. As that effectively changes the policy from allow=Store to allow=Store-and-Other-and-Developer it unblocks installing the not-Store-signed DDLM packages.

NOTE: I simplified the details a tad. The pedantic explanation would only complicate matters to no benefit understanding the issue. Yeah, I know, sorry for the length but that was the 'simple' explanation ;-)

Today most of WinAppSDK's Stable release's packages are Store-signed. Most, not all. We're investigating solutions to make this pain point go away for the currently-not-Store-signed DDLM packages but...it's complicated. Very much an active effort, but it'll take time to resolve. Please bear with us and thank you for your input, and your patience.

rcohn commented 2 years ago

Thank you for the comprehensive description of the package and app signing modes. From this description, then, it seems that apps that are installed on Win10 and Win11 with allow=Store-and-Other is the way to assure that the app will be allowed to run - assuming that mode is set.

In our case, we are now configuring our unpackaged WinUI3 desktop app as WindowsAppSDKSelfContained and, so far, that seems to be working as desired on the Win10 and Win11 desktop systems we've been testing on. Essentially, the folder of app files containing libraries and assets, with whatever runtime support is needed by using the self-contained option, are copied to a location on the target machine where the app executable can be run. We are no longer trying to install WindowsAppRuntime as part of the app installation process. There are no explicit things we've done to alert our testers to change to developer mode or not. To my knowledge, I don't believe anybody has tried installing the app on a server.

Are there any 'gotchas' using this approach that we should be aware of?

Thanks again for your great help.

DrusTheAxe commented 2 years ago

Are there any 'gotchas' using this approach that we should be aware of?

The tradeoffs of WindowsAppSDKSelfContained = false vs true (aka framework-dependent vs self-contained) are documented here => https://docs.microsoft.com/en-us/windows/apps/package-and-deploy/deploy-overview

rcohn commented 2 years ago

I had seen this table. Right now, self-contained appears to be the best solution to avoid runtime dependency problems.

Thanks once again. Best regards.