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.86k stars 328 forks source link

Add per-machine storage support to MSIX #13

Open wjk opened 4 years ago

wjk commented 4 years ago

Proposal: Add per-machine storage to MSIX

Summary

Even after several years, MSIX still has some significant limitations when compared to Win32 installation technologies such as MSI.

Rationale

Note: For purposes of brevity, I will refer to this per-machine storage feature as PMLS.

Scope

Capability Priority
When an app reads from PMLS, all local users will read from the same data Must
An elevated process in a Desktop Bridge package can write to PMLS Must
PMLS is only cleared when the app is uninstalled by all users on the PC Could
A process running outside the Desktop Bridge package can write to PMLS Could
An app must use a specific schema or format of data to store it in PMLS Won’t
An unelevated process can write to PMLS Won’t

Implementation Notes

Open Questions

jonwis commented 4 years ago

Check out https://blogs.windows.com/windowsdeveloper/2016/05/24/sharing-your-local-app-data/ - MSIX supports a "shared publisher cache" that IT admins can run. It doesn't accomplish your "writeable by admin, readable by all" requirement.

I'll think some more on this - there might be a way to accomplish it today, but you'd need some Power Tooling. The "remove on last user uninstall" is frankly the hard part since we like metadata-driven-only uninstallation. Definitely something that a Reunion API could help with.

wjk commented 4 years ago

@jonwis I didn't know that. However, seeing as it requires a machinewide Registry value to be set, what is the best way I ensure that the admin/user installing my app does so? I certainly can conditionalize the use of this feature, and store the license for the local user only if it’s not enabled, but how should I best document the process for enabling the shared publisher caches?

Also, I don't need the "writable-by-admin-only" setting to be actually enforced by the system; I can use an old-fashioned Group Policy (or similar) to disable the UI features that modify the licensing data for non-admin users. And the "remove-on-uninstall" is really a nice-to-have. I’ll edit the table above. Thanks!

jonwis commented 4 years ago

Well, if your app is going to elevate on first launch by administrator to write the shared location, maybe it could also set the group policy? Do note that this would be unexpected on end-customer machines that aren't under group policy control. So this isn't a slam-dunk answer, but something to think about.

I still think your shared location suggestion is useful, so I'll leave the issue open - close it if you think you have enough, or add more suggestions on how you'd like to see it work.

wjk commented 4 years ago

Unfortunately, if I elevate, won’t then the Registry value still be redirected into the app’s private hive, as I am running a process from within the MSIX namespace?

wjk commented 4 years ago

@jonwis Question for you. Having researched the Package Support Framework, I am wondering if the following process, which was inspired by how PowerShell scripts are run there, would be useful for enabling the Registry value for Shared Local caches:

  1. If the change is required, prompt the user with a dialog box stating what will happen. Provide OK/Cancel buttons. Make it clear to the user that they will need to provide elevation credentials if OK is pressed.
  2. Launch a helper process with PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY specified such that the it is launched outside the AppX context.
  3. The helper process immediately relaunches itself elevated using ShellExecute/runas; the user will be prompted to elevate here.
  4. If that checks out, the elevated helper process sets the Registry value to enable Shared Local caches.
  5. The main app waits for the helper processes to exit; it then can check to see if the Shared Local cache is now enabled and, if so, use it!

The only thing that makes me slightly iffy about this idea is https://github.com/microsoft/ProjectReunion/issues/16#issuecomment-630964492. You have said that running custom code outside the AppX container as part of an install is generally seen as a no-no. Note that this would be the only thing that would affect the system outside of the AppX container, and it would technically happen on first-launch, not during installation proper. Would this process be acceptable from a design standpoint? Thanks!

ghost commented 4 years ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 10 days. It will be closed if no further activity occurs within 10 days of this comment.

stevewri commented 4 years ago

@jonwis, can you take a look at @wjk's last questions?

DrusTheAxe commented 4 months ago

ApplicationData.MachineFolder should address the issue for per-machine storage

Will that suffice to meet your scenario?