Tech Community Live: Windows edition
May 31 2023, 07:30 AM - 11:30 AM (PDT)
Microsoft Tech Community

Combining optional packages and modification packages

New Contributor

Hi. I've a question that relates to both optional packages and modification packages.


I have created a "related set" consisting of an .msixbundle (the main package) and an .msix (the optional package). These packages are for sideloading, not for the Microsoft Store. Each package contains standalone executable applications.


I have also created a modification package that adds additional files (specifically, configuration files) to the virtualised filesystem of the main package.


The issue I have is that I want the applications that are part of the optional package to run in the same virtualized context as the main package. Meaning that:


- they would see the same virtualized filesystem;

- they would see the same virtualized registry;

- the modifications made by the modification package would take effect also for the applications in the optional package (so installing the modification package would provide configuration both to the apps in the main package and to the apps in the optional package).


However, the observed behaviour is that the apps in the optional package have a separate virtualized filesystem from those in the main app. Is there a way to change this so that they see the same virtualized resources?


I've also asked a couple of questions about this on Stack Overflow:

10 Replies

The plot thickens...


I just did some experimentation with running Regedit.exe via Invoke-CommandInDesktopPackage. I was expecting that the two apps would appear to have separate virtualized registries, as with the VFS. But in fact it seems as though they are sharing a virtualized registry. We may be able to switch to using the registry for config instead of configuration files.

The previous remark about storing configuration in the registry, or indeed in some filesystem location other than in the Program Files folder (alongside the executables) is premature. The design of the relevant facilities in .NET Framework really, really doesn't want you to put (for example) a Connection Strings file anywhere other than at a path relative to the executable. So I need the connection strings file to be in the virtualized file system, but that means that the apps in the optional package are unable to read it because they don't share the same virtualized file system! It is as though whoever at Microsoft designed MSIX did so with deliberate contempt for the people who designed the configuration file system!
Did you get anywhere with this? We've just hit the same problem (Optional Package cannot see overlay from Modification Package), and were working on the assumption it would work based on the line "Optional packages and related sets all run inside the main app's MSIX container" in the documentation here:
Just to expand on this, I've used Invoke-CommandInDesktopPackage to run PowerShell inside the container and have verified that the files added by the Modification Package are showing up in the VFS, but they are not detected by the application being launched from the Optional Package.

If I make the app in the Optional Package into a Main Package, then change the Modification Package to apply to that, the file is detected correctly.

Based on this, it looks like:
* When the application is the Main Package it can load files (in this case, DLLs) that have been applied by a Modification Package.
* When the application is an Optional Package on top of a Main Package, it cannot load files that have been applied by a Modification Package.

Is this intentional? It doesn't seem to gel with what I'd expect, particularly now I've confirmed the files are in the expected place in the VFS.
@JDHIntercede I'll admit to being a bit confused by creating a related set and optional package.

If I want to have a primary package with a modification package that contains either different files or registry settings and this modification package contains no entry-points (Shortcuts/FTAs, etc..) Then all I need is the primary package and a package created as a modification package.

I believe that it is necessary that files in the primary and modification package exist as VFS files in their respective packages for the layering to work. (This is a restriction that Microsoft should, and may have fixed, but as I've never seen that they did I always make the packages this way).

The modification package references the main package by using the full package family name, and may not be installed until after the primary package is installed.

As such, all changes made by the app when running with the modification package are redirected based on the primary package family name.

@TIMOTHY MANGAN Hi Tim, yes the basic case isn't an issue; main package can read files from a modification package no problem. What I'm having issues with is that Optional Packages don't seem to share the same context.

For context, this is what I'm trying to do (finally picking it back up): Multi Application Suite? - Microsoft Tech Community

So, what I have is:
* Main package, which is a simple configuration tool

* Several optional packages, all in a related set with the main package, which contain related but standalone applications in the suite. Customers may install any combination.

* In all of the packages, the entry points are inside the ProgramFilesX86 VFS directory. 

* When I add a modification package with, say, a DLL, the main package can load it but the optional packages act like it doesn't exist. 

* I've used Invoke-CommandInDesktopPackage to verify the modification package files are in the VFS, but I believe this is running the command in the context of the main package so doesn't help confirm what the optional package can see from its context. 

* If I break-apart my suite, make one of the optional packages into a main package, then create a modification package containing the same file, the application can see it. 


I've tried including the modification package inside the related set, but this has had no effect. The only way I can see to make an application load from a modification package is for the application itself to be the main package. 


Why am I doing this? I wanted a single route to install different combinations of apps in an MSIX 'suite' (e.g. differently configured appinstaller files for different user groups, etc). The modification package that gets overlaid contains a separately-licensed plugin that should be accessible from all of the applications in the container - from what I'm seeing, this isn't achievable even though all the docs seem to indicate that optional packages should get the same VFS overlays as the main package.

I guess the problem I'm now having is that, because Microsoft hasn't documented optional packages at all well, I can't tell if this is intentional or a bug. It seems strange that optional packages can have entry points, all the docs say they share a VFS, but I'm finding they can't load the same files. If this is the case, then there's no way to customise an application with a modification package if it was delivered as an optional package, which seems like something of a gap. It also completely blocks MSIX for us, as the single experience was the main goal.  



I regret that I never got any further than my previous messages here indicate. The reason why I never pushed any further on this is that we revisited our design decisions, and changed them in such a way that the architecture I had planned (main package + optional package + modification package modifying both) was no longer the favoured approach. It does sound as though the problem you are currently facing is the same problem we encountered.

As the previous poster said, the plot thickens! The issue appears to be around how the VFS is overlaid for optional packages, and what that means for relative paths:

Working (Main Package -> Modification Package):
* Given a main package with VFS\ProgramFilesX86\somefolder\myapp.exe
* Install a modification package that adds VFS\ProgramFilesX86\somefolder\somelib.dll and VFS\ProgramFilesX86\somefolder\someconfig.xml
* MyApp.exe can see both modification package files relative to itself; that is to say, for example, we could call File.ReadAllText("someconfig.xml") and it would succeed. .NET can also load somelib.dll without issue.

Not Working (Main Package -> Optional Package -> Modification Package)
* Given a main package with VFS\ProgramFilesX86\somefolder\myapp.exe
* Install an optional package that adds VFS\ProgramFilesX86\somefolder\myotherapp.exe
* Install a modification package that adds VFS\ProgramFilesX86\somefolder\somelib.dll and VFS\ProgramFilesX86\somefolder\someconfig.xml
* MyApp.exe can see both modification package files relative to itself.
* MyOtherApp.exe cannot see either somelib.dll or someconfig.xml relative to itself. .NET cannot load somelib.dll (FileNotFoundException).

Possible workaround (Main Package -> Optional Package -> Modification Package):
* Given a main package with VFS\ProgramFilesX86\somefolder\myapp.exe
* Install an optional package that adds VFS\ProgramFilesX86\somefolder\myotherapp.exe
* Install a modification package that adds VFS\Common AppData\somelib.dll and VFS\Common AppData\someconfig.xml
* Both MyApp.exe and MyOtherApp.exe can see and load someconfig.xml when we manually use the Environment.SpecialFolder enum to get the path to CommonAppData.
* Working theory is that if we use Assembly.LoadFrom(filepath) in MyOtherApp.exe, passing the CommonAppData\somelib.dll path we generated using the Environment.SpecialFolder enum, then we should (hopefully) be able to load the DLL before .NET tries to do it automatically.

The more I look into this, the more it seems like a bug in the way modificaiton package overlays are being applied when there are optional packages in place, as I cannot for the life of me see why you'd want it to work like this.

@JDHIntercede You'll probably need someone from Microsoft to confirm, but I suspect that optional packages are not designed to layer in as you'd like.


However, on Windows 11 (only, unfortunately), it might be possible to add a Shared Package Container (SPC) that lists your mainpackage and optional package.  I think the modification package would automatically come in as long as it is deployed, but possibly that would need to be listed as well).  The packages listed in the SPC are all considered optional, so what the user gets is independent of the SPC definition.  The SPC is (unfortunately) separately installed as an XML file definition listing the packages and a layering order (in case there are any file/reg conflicts).   The SPC may be installed either prior to or after any of the packages.  See MSIX Shared Package Container - MSIX | Microsoft Docs 

best response confirmed by TIMOTHY MANGAN (MVP)

In case anyone is interested, and just so I don't leave another dangling thread, this is the redesign we've ended up going with:

* All apps are included in the main package, but only the config tool has an entry point (ergo only one with a Start entry).
* Optional packages add simple exes that launch the existing applications from the main container. The exes are registered as entry points, effectively allowing us to add Start entries for the apps that are already installed in the main package.
* Since all the apps are actually in the main package, even though they are only enabled when the optional package is installed, they can all see any DLLs and whatnot that have been overlaid by modification packages relative to their assemblies - this means we can ship our separately licensed components without any problems.

This works for us since there isn't any licensing issues with the apps themselves, just the components we want to ship in modification packages, and we really just wanted the admin to be able to choose what they add to the Start menu. The apps themselves aren't very big either, so including them all in the main package isn't a problem.

Hopefully this is useful to anyone trying to do something similar. I'll also link here from the other thread for anyone getting here from a web search.