Forum Discussion
Bad experience with app container virtualization and workarounds
Hi MikeH
I don't work for Microsoft and this answer is just my personal experience and opinion.
That being said, MSIX is a relatively young technology compared to MSI and the entire Windows OS, it takes time to get it done properly.
1) I've hit this too but in a different way. The scenario you're presenting does not apply because all the files installed by an MSIX are read-only, so even if Notepad would "see" the file, you couldn't overwrite the installed version.
The problem I hit here was with apps that included a documentation file in the install folder, for example, an HTML that was failing to load within a browser (which of course is not part of the package container).
Using the Package Support Framework, we could develop a generic fix for this type of problem. But as you said, it would have been nice to just work.
2) MSIX Hero and Hover (a free app we've built) use the built-in OS support to launch a process inside the container of a package, basically a silent execution of the PS cmdlet:
Invoke-CommandInDesktopPackage
If MSIX Hero or Hover can't get the job done you can try to run the cmdlet manually, using other params, since these tools only execute the cmdlet with the most command combination of params.
6) Digital signing does not guarantee the lack of virus inside your code, therefore AVs will continue to check this code and sometimes give us headaches with false-positive detections (even if the package is signed). Where the digital signature helps is with mand in the middle attacks and in enterprise infrastructures where most MSI/EXEs built internally were deployed without any digital signing (making it easier for many bad actors to inject a virus inside).
> don't write files into AppData.
Why? Do you have problems because this date is removed upon uninstall? How do you roam your app settings from the user profile home directory, in enterprise environments? (AppData has builtin roaming support)
As you probably know AppData is recommended to be used only for storing application data/settings, not the user data. For user data, you can use a library like My Documents as the default and let the user specify a different location.
Bogdan Mitrache Thanks for the tips. I tried Hover, thanks for releasing it, it's a nice app. I noticed it uses MSI 😉 Actually the kind of no-fuss one-click install you've got with Hover is pretty much what I'd like to have, are you making that using WiX?, that's being made with your Advanced Installer product, right?
W.R.T. notepad the actual use case in my app is viewing or sending/attaching a log file. So read-only is fine. It looks like you guys developed a fixup that can modify command line arguments, is there a Win32 API to devirtualize file paths? I haven't yet experimented with the manifest feature that lets you expose files to other apps, perhaps that's the way to go.
Re: running inside the container. Do you or anyone else know how this PowerShell Cmdlet works internally? Again, is there a Win32 API for this? Or is running a PowerShell sub-process actually the official API for doing this kind of thing? Is there a way to make sub-processes reliably run in the same container by default? The docs suggest it should happen automatically but obviously that isn't the case. In my case, my app is running "cmd /c 'some command'" and it's cmd.exe that complains it can't find the directory, presumably because it's been started outside the container.
W.R.T. not using AppData - yeah, I know why AppData is there and it will cause problems not to use it because the files in question are actually mostly a large file cache. It's not really user data and the only reason to write it to the home dir is to escape the virtualization layer whilst still having a GUI install. So it won't roam well and I'm already looking for workarounds there, like maybe finding a cache directory under c:\windows or something like that. It needs to be somewhere sub-processes work because I invoke them inside this large private file tree.
Finally, with the virus scanner, I understand that malware authors can buy or steal signing keys, but then that rather suggests that the whole idea of revoking malware keys or using them for legal enforcement is a bust. If Microsoft want their operating system API to heuristically guess whether to allow basic low level operations or not, then it needs a top-class debugging and diagnostics experience. The app works fine when it's not signed and running outside of the installed version, presumably because it's a Java app and so perhaps the high-reputation JVM signature takes precedence. The moment I sign it, the app breaks in subtle ways that only show up during a full test cycle, without any information that it's done so, in ways that are difficult to debug. I will probably try signing it with an EV key next.
- Bogdan MitracheDec 23, 2021Iron Contributor
Hi MikeH
Yeah, the MSI package is built with Advanced Installer. You can build a similar package with the freeware edition and use it for as long as you want. This isn't a separate download, it's the same full version, the freeware features are included in the Simple project.
We've built a lightweight MSI because admins using the tool were asking us to provide something with the smallest footprint possible. Some even asked us for a ZIP because they don't want to use additional tools on their packaging/testing machines. So, we are testing this "ZIP deployment" for another tool now, the MSIX Troubleshooter, we'll see how this goes.
Of course, we evaluated packaging it as an MSIX but this just wasn't the best option for our users at that time. We will probably re-evaluate it.For the command line arguments, we use our own launcher. It is a custom version that also integrates the PSF launcher from Microsoft. We had it before PSF was launched so we kept on improving that with what Microsoft released.
For accessing files from inside the package with an external process, like Notepad, we rely on the package support framework. Here is an example where a process from the container launches Notepad and gives it as param the file path from the container. I don't have the details on this implementation as the colleague that worked on it is on vacation.Re: running inside the container. We don't know anything more than what is documented in the public docs. We don't use any Win32 API.
The only problem/limitation I had with it was that it could not launch explorer.exe inside the container, but in other cases, it usually worked.Re: The moment I sign it, the app breaks. Have you tested the signed application without packaging it as an MSIX? It is strange for an app to crash just because it is digitally signed. The container, on the other hand, could be a source of headaches. We would all love a better debugging experience and I fully support your feedback to Microsoft, that is why I just added my feedback on the parts where I considered useful.
- MikeHDec 23, 2021Brass ContributorThanks. I haven't tested signed-but-unpackaged, I'll do that once I finish my current pile of bugs.
I've found a workaround for the subprocess/VFS issues. If sub-processes are run in the redirected path then they seem to work properly, or at least cmd.exe does. So that leaves the question of how to know where the redirected path is.
My solution is to, at startup in native code, change the values of the LOCALAPPDATA and APPDATA environment vars (which my app uses) to be the output of SHGetKnownFolderPath with the KF_FLAG_RETURN_FILTER_REDIRECTION_TARGET flag. This returns the path that Windows is redirecting writes to. By using this location directly instead of relying on the redirection, it appears to have fixed my issue. The nice thing about this is, it will automatically work for any program that uses the right environment variables in the process tree.
This preserves the VFS functionality whilst working around whatever bug is breaking things.