MSIX Shortcuts Revised

These last couple of weeks I have been busy researching into problems some customers were having with MSIX packages with shortcuts. This post will bring you up to date on some new information on how MSIX works, and details on how TMEditX is changing handling these issues starting in version 4.6.

History of the source of the problems

Traditionally applications created shortcuts by dropping a lnk file in one of the start menus (one per-machine and one per-user). The lnk file contains a target executable with optional command line arguments, and optionally a working directory and icon. Items could be grouped into subfolders (and even multiple level subfolders). And there is a special start menu folder called “Startup” which is a place for apps that should launch automatically when the user logs in (one of several techniques to do this). The explorer process that runs your desktop was responsible to monitor these locations and provide the start menu.

Oh, and the app installer could also drop them on the desktop, although in deploying apps in the enterprise we usually want to remove the desktop shortcuts.

In MSIX, those are converted into entries in the AppXManifest. While the original lnk files might be left in the package, these are not consulted and the AppXManifest entries are used when the package is installed to add things into the start menu.

Early on in MSIX there were a lot of restrictions on what could be in the AppXManifest to generate entries into the start menu. Any given exe file in the package was limited to only one start menu entry, and it couldn’t have any command line arguments. The xml element used to contain this was part of the Uap2 schema extension and called VisualElements; this was placed as a child of the Application element pointing to the exe to run.

To get around some of the limitations, we often used the Package Support Framework. A copy of PsfLauncher.exe could be added to the package for each shortcut we wanted, and the PSF config.json file would identify the exe to be run, the arguments, and the working directory.

Later on, Microsoft extended the AppXManifest schema with two things:

  1. Microsoft created a new Uap3 schema extension for VisualElements which added a new parameter for the start menu folder, called VisualGroup. With this you can add a single level folder to group the start menu items in this package under.
  2. Microsoft later created a new Desktop7 schema extension. This schema extension may also be added as a child of the Application, and it may contain multiple desktop7:shortcut elements, each of which can have different shortcut names, arguments, and icons.

In late 2022, Microsoft changed the MSIX Packaging tool to start adding these into captured packages, but they did not work, and we routinely removed them when fixing up the packages.

The dilemma

Removing the desktop7 shortcut element solved the problem of not being able to install the packages, but it meant that we had to rely on the PSF to get multiple shortcuts to the same program and for command line arguments.

What we learned about Desktop7 shortcut schema extension

Normally, in the AppXManifest any file references are listed as file paths relative to the root folder of the package.  For example, the application executable might appear as “VFS\ProgramFiles64\Vendor\App.exe”.

The desktop 7 shortcut has two file references, one for a “File” and another optional item for an “Icon”.   But the file references here are quite different.   Here is an example from the MSIX Packaging Tool:

<desktop7:Extension Category="windows.shortcut">

<desktop7:Shortcut File=”[{Common Programs}]\Xming\Xming.lnk Icon=”[{Package}]\VFS\ProgramFilesX86\Xming\Xming.exe Arguments=”:0 -clipboard -multiwindow/>

</desktop7:Extension>
 
We now know that this is the same format as used in the container virtual registry for values that look like file paths but applied as the equivalent relative package or VFS path.  Thus, the File argument is the same as “VFS\Common Programs\Xming\XLaunch.lnk” relative to the root of the package.
 
The failure we’d see when trying to install this package is due to the AppInstaller trying to read the contents of this file.  First of all, the file must be present in the package.  In packages captured in the MSIX Packaging Tool this is generally the case, but not so for applications converted from App-V packages by the same tool – that conversion stripped out the lnk files as not needed!  But even if the file is present, the value of the “target” must be referenceable; the file path in the lnk file, however, would be for a native location and so when that file isn’t found the install also fails with a file not found error.  Which is strange as the end-result doesn’t even use that target exe, it actually uses the executable listed in the parent Application record. 
 
Furthermore, the Microsoft Documentation for this element incorrectly describes the File parameter:
The path to the file that is the target of the shortcut.

Add to this forum posts by Microsoft employees showing examples where the value of the File parameter was directly an exe (when it must be a lnk file).  No wonder we couldn’t get it to work!  And to top it off the Icon can’t point to an exe/dll to pull it from the resource section.  But it can either be an ico or png file.

By the way, I also want to caution everyone not to call these “desktop shortcuts”, as is often done in forum posts.  This is really confusing to all of us, but especially IT folks that think of desktop shortcuts as lnk file placed on the desktop.  The desktop in this schema extension means that the extension is intended only for packages installed on Windows, as opposed to UWP apps or Maui (the newer multiple platform solution for developers).  So let’s all just learn to say “Desktop7 Shortcut” when referring to this. 

MSIX does not have any support that you can add to the package to cause a desktop shortcut to be added upon installation of the package! And we also get asked about this quite a bit.

The new solution 

So here is what I am doing about this now.

If the application has multiple shortcuts to the same exe, we will always inject the PSF and remove the desktop7 shortcut element. This injection will add copies so that each application element creates only one start menu entry, via the VisualElements element.

Otherwise, when there were not multiple shortcuts to the same exe, if we have other reasons to add the PSF, we similarly get rid of the desktop7 shortcut element.

Otherwise, when there is no PSF, we fix the desktop7 shortcut.  This may involve creating a new lnk file and adding it into the package, but also correcting the value of the File parameter.  We also replace the Icon reference by pointing to the same PNG file as in the Application element (just changing the reference into this Registry format).

Bonus Fixes

We are also doing a better job with the VisualGroup now in TMEditX.  If we detect that the original shortcuts used a subfolder, or if the lnk was missing but the incorrect File reference indicated a subfolder, then we add the VisualGroup.  If multiple levels of subfolders were used, we just consolidate using the top-level subfolder.  If the package ends up with only one shortcut, we take the VisualGroup out since that would be simpler for the end-user.

And while sorting all this out I found  some edge cases of missing shell verbs (right click Edit/Open/etc) that also had command line arguments.  These are now properly detected and fixed by TMEditX.

 

By Tim Mangan

Tim is a Microsoft MVP, and a Citrix CTP Fellow. He is an expert in App-V and MSIX.