Skip to content
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

Add per-machine storage support to MSIX #13

Open
wjk opened this issue May 19, 2020 · 8 comments
Open

Add per-machine storage support to MSIX #13

wjk opened this issue May 19, 2020 · 8 comments
Assignees
Labels
area-Deployment Issues related to packaging, installation, runtime (e.g., SelfContained, Unpackaged) feature proposal

Comments

@wjk
Copy link

wjk commented May 19, 2020

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

  • As a developer of a Desktop Bridge app, I cannot store licensing data in a common location that is not also easily erased. I can't store this in the app's private Registry, as then (a) it's per-user only, so I (or the admin if in an organization) have to enter the licensing information for every user that uses the app. Also, if the user resets the app in Settings (perhaps because it's malfunctioning), the license information will be erased as well, causing confusion and annoyance (and probably a call to the help desk so IT can reenter it).

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

  • I can accomplish this today by (ab)using customInstallActions to install a small support program that runs outside the MSIX container (so it can modify the shared HKLM hive), and the app then funnels all PMLS write operations through it.
  • This feature may be best implemented as an extension to the MSIX manifest format, which will not function correctly on downlevel version of Windows. We may need to do something to my workaround above backport this functionality to older versions of Windows.

Open Questions

  • Should I provide a way for an elevated app to write to another package’s PMLS? This would be useful to installation or automation tools to write licensing data in an automated process, without needing to launch the app and manipulate its UI. Note that I could accomplish this today by using a console EXE in the AppX package that accepts a license key, and then using the existing support for putting packaged EXEs in the PATH to make it available.
@jonwis
Copy link
Member

jonwis commented May 19, 2020

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
Copy link
Author

wjk commented May 19, 2020

@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
Copy link
Member

jonwis commented May 19, 2020

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
Copy link
Author

wjk commented May 19, 2020

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
Copy link
Author

wjk commented May 21, 2020

@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 #16 (comment). 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!

@stevewri stevewri added the area-Deployment Issues related to packaging, installation, runtime (e.g., SelfContained, Unpackaged) label Jun 10, 2020
@ghost
Copy link

ghost commented Jul 23, 2020

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.

@ghost ghost closed this as completed Aug 2, 2020
@stevewri stevewri reopened this Sep 28, 2020
@stevewri
Copy link
Contributor

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

@DrusTheAxe
Copy link
Member

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

Will that suffice to meet your scenario?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Deployment Issues related to packaging, installation, runtime (e.g., SelfContained, Unpackaged) feature proposal
Projects
None yet
Development

No branches or pull requests

7 participants