The new TMEditX 5.0 Mega-release

TMEditX is the licensed and much more capable tool for fixing up MSIX packages, better than PsfTooling since it doesn’t have to depend on the Microsoft MSIX Packaging Tool to create the final package.  [Download_page]

TMEditX 5.0 has been released!

This is a big release, significantly improving your ability to get more apps working under MSIX.  Preliminary app-compatibility testing against this release shows significant gains! The list of changes in this release is rather long, so we’ll give you the overall list first, and then highlight three of the more important items.

NOTICE:

NOTE: Due to a change in the code signing certificate, 5.0 is not an upgrade package.  You must remove the old TMEditX before installing this version and re-configure the tool.

 

TMEditX changes:

  • Updated to PSF v2024.08.05 – See blog post New addition to the PSF: PsfFtaCom – Confessions of a Guru (tmurgent.com) that includes the new PsfFtaCom component.
  • Added the detection, and fix, of packages with shell verb commands that point to different applications. More on this below.
  • Added the detection, and fix, of packages that have COM or Shell Extension issues that require the new PsfFtaCom style of fix. More on this below.
  • Added support for new AppXManifest Schema extensions: Uap15, Uap15a, Uap16, Uap17, and Desktop11.  While Microsoft included these schemas in the latest SDK, we currently do not have documentation on them, especially on what OS version is required (we are guessing 24H2, but could be later).
  • Added support for editing package with long relative file path lengths.
  • Add detection, and fix, for .lnk style shortcuts that have a URL for the target program.  Previously we only supported .url file types for this.  
  • Added support for editing packages with certain character sets used in filenames, such as Japanese.  These files were previously ignored while unpacking.
  • Added detection/fix for shortcuts to a folder (launching explorer.exe to that folder).
  • Added detection/fix for a captured PATH variable change. This fix uses the LoaderSearchOrder feature of MSIX.
  • Added detection/fix for previously ignored Shell Verb commands that used characters in the verb that were supported natively but not in the AppXManifest schema. The illegal characters, any non-character or digit (often an & or _), are removed.
  • Added detection/fix for Shell Verb Commands that included complicated file paths not previously supported.
  • Added support for shortcuts to the 32-bit version of cmd.exe.  Previously, only the 64-bit version was supported.  Also supported are shortcuts to any external OS supplied exe that is in the Windows and SystemX** folders.
  • Added a configuration option, and command line options, to control what to do about shortcuts that were on the desktop. Previously, these were removed from the package as IT generally wants to do this.  With this option enabled, the desktop7:shortcut entry will be fixed (if necessary) instead of removed.  The default configuration remains to remove the desktop shortcuts.  The new command line options are /AutoAllowDesktopShortcuts and /AutoRemoveDesktopShortcuts; these will override the default of configured setting.
  • Changed logic on “Reasons you need the PSF” to exclude consideration of files that are part of the exclusion list.
  • Changed logic on “Reasons you need the PSF” to include detection of Electron based apps.
  • Added a new category on the analysis page called “Unfixable Issues”.  This now contains any items that previously were listed under the recommended/available lists but cannot be fixed.
  • Added detection and reporting of executable files that won’t run natively on an Intel/AMD x64 processor, including 16-bit, ARM, and ARM64.  This appears in the new Unfixable issues list.
  • Added detection/fix for AppPaths style path registrations that were using registry style paths like [{ProgramFilesX64}]. These now are converted to Application Aliases as long as the file is in the package. If file path is not in the package the entry is ignored (this was breaking packages created on systems where Windows Updates occurred during packaging).
  • Added new command line option /RunUiMinimized.  This is intended for scenarios where TMEditX is run as part of an automated packaging sequence.
  • Fix bug when adding the PSF to a package that already had a UAP3:VisualElements element.
  • Fix for any command line arguments that contain registry format filepaths that end up in the config.json file.  Previously only some sources of these paths were covered.
  • Tidied up the File->Options setting page to make it more readable and organized.
  • Added a new feature, the creation of the Analysis Report file.  More on this below.
  • Added support for package signing using a certificate stored on a hardware token, such as used by Digicert.

MsixDeploy Changes:

  • Added support to display the new analysis report file on the UNC listing page.
  • Added detection of PsfFtaCom in the package, now shown in the PSF component list on the UNC package listing.
  • Added detection of services in the package, now shown on the UNC package listing and installed package listing.

Shell Verbs

The Microsoft implementation for shell verb commands is to place the verb under the fta element of an application.  In the AppXManifest schema, the exe listed in the traditional registry style of FTA registration is not contained in the verb element but is assumed by the placement of the fta inside an application element. The executable parameter of the application element is assumed to be the command portion for the verb, which then defines any command line arguments.  This is fine for many packages, but not if the package contains multiple applications and there are shell verbs for the same file type (such as a “View” verb and a “Edit” verb) where the verb commands are for different exe files. The underlying issue is that the AppXManifest schemas did not allow for the same file type association to exist in different application elements of a given package.

This is now solvable by the new PsfFtaCom component of the PSF.  We now place all of the FTAs and Shell Verbs under a new application entry in the AppXManifest, adding the relative filepath to the executable in the Arguments parameter of the Verb.  When the user executes the right-click on the shell verb, the system starts up PsfFtaCom with the arguments field of the verb (possibly extended with the path to the clicked-on file at the end of the arguments).  PsfFtaCom then strips off the leading file path as a command to run and passes the remaining arguments to that command. 

More information on PsfFtaCom, including examples, are on the wiki page here: PsfFtaCom · TimMangan/MSIX-PackageSupportFramework Wiki · GitHub

PsfFtaCom for Shell Extensions and COM

We have been struggling with getting COM registrations of packages into the AppXManifest.  Previously, TMEditX included a number of detections and fixes for specific issues, some of which included dummy applications and anti-disregardation.  Often, this is because of multiple uses of a COM based file that would run afoul of AppXManifest Schema uniqueness and element-level completeness rules. This was especially true when there was a shell extension involved (which is then tied to an FTA and the file type may only be listed in a single application element).

The AppXManifest has both application-level and package-level extensions that include certain COM elements.  The simplest solution (which I suggested 6 years ago) was to allow the COM elements to all be defined as package-level, and then either also move the Shell Extensions to package-level, or let them reference the COM guid when it is package-level.  Microsoft never acted on this suggestion, but we have now worked out a way to handle most of these issues within the constraints of the AppXManifest Schemas by using a PsfFtaCom application in the package.

When we need to make Shell Extension or COM changes to the manifest (or anytime the PsfFtaCom is added for the shell verb case), we add the PsfFtaCom element to the package as an additional application and move any existing shell extension or application-level COM elements to this application element.  We can then add in the missing shell extensions and COM elements under this element.

The shell extensions and COM pieces never invoke the PsfFtaCom.exe (just as they never invoked the application they were previously under), so this now acts as a pseudo second package-level place in the AppXManifest file.

More information on PsfFtaCom, including examples, are on the wiki page here: PsfFtaCom · TimMangan/MSIX-PackageSupportFramework Wiki · GitHub

Analysis Report

One of the additional challenges for an organization’s Desktop Engineering team is that they are often dealing with packaging up applications that they know nothing about.  This causes unnecessary delays in getting new apps out to the end-users waiting for them.

This release adds a new XML file in the package that contains information gleamed during the package analysis which may be of use in several ways:

  • It provides a form of package documentation, possibly replacing the need for manual documentation.
  • It documents key integration points on how the application may be started from evidence left behind by the original native installer, including shortcuts, file type associations, shell extensions, and protocol handlers.  These can be viewed and then used as part of the “smoke test” before sending the package off to UAT test.  In the future, third party automated package testing might be able to use this information directly to create better testing.
  • It documents the initial analysis (normally seen only in the GUI) and then the changes made to the package by TMEditX. This information will be of use by a senior packager to better understand what has been done and what else can be done to fix the package.
  • It documents the package dependencies and any items seen in the package that are not fixable.

This file, AnalysisReport.xml, is placed in the root folder of the package.  An external file was considered, but keeping this inside the package seems to make the most sense.

An example from TeamViewer is shown here:

<AnalysisReport Package="TeamViewer">

<InputPackage>
<!– Information about the package as input to TMEditX. This contains information regarding the determined intent of the original installer, as captured by the original repackging tool. –>
<PackageSourceDetermination MicrosoftMSIXPackagingTool=”true/>
<PackageType IsNormalPackage=”true/>
<PackageStatisticss NumberOfFiles=”127 NumberOfRegKeysAndValues=”416 HasPsfInitially=”false/>
<EntryPoints NumberEntryPoints=”1>
<EntryPoint Name=”TeamViewer.exe>
<Shortcuts>
<Shortcut Name=”TeamViewer Type=”Lnk Target=”C:\Program Files\TeamViewer\TeamViewer.exe/>
</Shortcuts>
<FTAs>
<FTA Ext=”.tpsr>
<ShellVerb Verb=”open Cmd=”“[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe” –opentpsr “%1”/>
</FTA>
<FTA Ext=”.tvc>
<ShellVerb Verb=”open Cmd=”“[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe” –control “%1”/>
</FTA>
<FTA Ext=”.tvs>
<ShellVerb Verb=”open Cmd=”“[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe” –play “%1”/>
</FTA>
</FTAs>
</EntryPoint>
</EntryPoints>
<Protocols>
<Protocol Name=”blizzv1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”teamviewer10 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”teamviewer8 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”teamviewerapi File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvchat1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvcontrol1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvfiletransfer1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvjoinv8 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvoneweblogin File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvpresent1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvsendfile1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvsqcustomer1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvsqsupport1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvvideocall1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
<Protocol Name=”tvvpn1 File=”[{ProgramFilesX64}]\TeamViewer\TeamViewer.exe Parameters=”“%1”/>
</Protocols>
</InputPackage>


<InitialSuggestedFixes>
<!– Information about the initial analysis by TMEditX. This contains information regarding the analysis of the original input package. –>
<PrePsfSuggestions>
<CleanupRegistry Count=”10/>
<CleanupFiles Count=”9/>
</PrePsfSuggestions>
<PsfSuggestions>
<Psf>
<Cause Reason=”Required: Psf FileRedirectionFixup/MFRFixup for native path visibility to package file(s):/>
<Cause Reason=” VFS\AppData\TeamViewer\TeamViewer15_Logfile.log/>
<Cause Reason=” VFS\SendTo\TeamViewer.lnk/>
<Cause Reason=”Recommend: Psf FileRedirectionFixup/MFRFixup (or ILV) for writing to package file(s):/>
<Cause Reason=” VFS\ProgramFilesX64\TeamViewer\Printer\TeamViewer_XPSDriverFilter-manifest.ini/>
<Cause Reason=” VFS\ProgramFilesX64\TeamViewer\Printer\TeamViewer_XPSDriverFilter-PipelineConfig.xml/>
<Cause Reason=” VFS\ProgramFilesX64\TeamViewer\tvinfo.ini/>
</Psf>
</PsfSuggestions>
<RecommendedFixes>
<Recommendation Type=”InstalledLocationVirtualization Candidate>
<IssueDetail Detail=”Add ‘InstalledLocationVirtualization’ to the AppxManifest./>
</Recommendation>
</RecommendedFixes>
<AvailableFixes>
<Item Type=”Copy dlls to System folders>
<IssueDetail Detail=”Copying package dlls to the System32/SysWow64 folders is an alternative solution to dll not found issues. Do this instead of, or in addition to, PSF DynamicLibraryFixup or LoaderSearchOrder./>
</Item>
<Item Type=”Copy dlls to PkgRoot>
<IssueDetail Detail=”Copying package dlls to the package root folder is an alternative solution to dll not found issues. Only applicable when all dlls are same bitness. Do this instead of, or in addition to, PSF DynamicLibraryFixup or LoaderSearchOrder./>
</Item>
<Item Type=”Add ‘Allow Elevation’ capability to AppXManifest>
<IssueDetail Detail=”Add ‘Allow Elevation’ capability to AppXManifest./>
</Item>
</AvailableFixes>
<DetectedUnfixable/>
</InitialSuggestedFixes>


<FixesApplied>
<!– Information about the fixes applied by TMEditX. This contains an ordered list of changes requested of the Analysis, additional manual changes outside of the Analysis page may have also been made. –>
<FixApplied Description=”RegistryCleanup>
<Information>The following registry keys/items were removed:</Information>
<Item Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\GlobalAssocChangedCounter/>
<Key Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer/>
<Key Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall/>
<Key Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion/>
<Key Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows/>
<Key Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Notifications/>
<Key Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion/>
<Key Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows NT/>
<Key Name=”REGISTRY\MACHINE\SOFTWARE\Microsoft/>
<Key Name=”REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Services\bam/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\OneDrive/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\CloudStore/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Internet Settings/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Search/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\UFH/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\Shell\Bags/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\Shell/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]\Software/>
<Key Name=”REGISTRY\USER\[{AppVCurrentUserSID}]/>
</FixApplied>
<FixApplied Description=”FileCleanup>
<Information>The following files/directories were removed:</Information>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Common Documents\SequencedPackage\Log_TeamViewer.txt/>
<Directory Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Common Documents\SequencedPackage/>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\UserProfiles\Default\AppData\Roaming\Microsoft\Windows\SendTo\TeamViewer.lnk/>
<Directory Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\UserProfiles\Default\AppData\Roaming\Microsoft\Windows\SendTo/>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\UserProfiles\Tim\AppData\Roaming\Microsoft\Windows\SendTo\TeamViewer.lnk/>
<Directory Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\UserProfiles\Tim\AppData\Roaming\Microsoft\Windows\SendTo/>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\UserProfiles\Tim\NTUSER.DAT/>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\UserProfiles\Tim\ntuser.dat.LOG1/>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Windows\Microsoft.NET\Framework64\v2.0.50727\ngen.log/>
<Directory Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Windows\Microsoft.NET\Framework64\v2.0.50727/>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.log/>
<Directory Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Windows\Microsoft.NET\Framework64\v4.0.30319/>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Windows\Microsoft.NET\Framework\v2.0.50727\ngen.log/>
<Directory Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Windows\Microsoft.NET\Framework\v2.0.50727/>
<File Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.log/>
<Directory Name=”C:\Users\Admin\AppData\Local\Temp\zqxyozoq.fp3\VFS\Windows\Microsoft.NET\Framework\v4.0.30319/>
</FixApplied>
<FixApplied Description=”PackageSupportFramework (PSF)>
<Information>The release build of Psf components will be used when adding the Psf to the package.</Information>
<FileInjection>Added PsfLauncher1.exe to Ingredients for VFS\ProgramFilesX64\TeamViewer\TeamViewer.exe</FileInjection>
<FileInjection>Add file to ingredients PsfRuntime32.dll</FileInjection>
<FileInjection>Add file to ingredients PsfRuntime64.dll</FileInjection>
<FileInjection>Add file to ingredients PsfRunDll64.exe</FileInjection>
<FileInjection>Add file to ingredients PsfRunDll32.exe</FileInjection>
<FileInjection>Add file to ingredients MFRFixup32.dll</FileInjection>
<FileInjection>Add file to ingredients MFRFixup64.dll</FileInjection>
<FileInjection>Add file to ingredients RegLegacyFixups32.dll</FileInjection>
<FileInjection>Add file to ingredients RegLegacyFixups64.dll</FileInjection>
<FileInjection>Add file to ingredients VFS\SystemX86\msvcp140.dll</FileInjection>
<FileInjection>Add file to ingredients VFS\SystemX86\vcruntime140.dll</FileInjection>
<FileInjection>Add file to ingredients VFS\SystemX86\ucrtbased.dll</FileInjection>
<FileInjection>Add file to ingredients VFS\SystemX64\msvcp140.dll</FileInjection>
<FileInjection>Add file to ingredients VFS\SystemX64\vcruntime140.dll</FileInjection>
<FileInjection>Add file to ingredients VFS\SystemX64\vcruntime140_1.dll</FileInjection>
<FileInjection>Add file to ingredients VFS\SystemX64\ucrtbased.dll</FileInjection>
<AppXManifest> Update FTA/Verb TeamViewerPilotSessionReporting/open to point to new command.</AppXManifest>
<AppXManifest> Update FTA/Verb TeamViewerConfiguration/open to point to new command.</AppXManifest>
<AppXManifest> Update FTA/Verb TeamViewerSession/open to point to new command.</AppXManifest>
<AppXManifest>Update application to point to PsfLauncher.</AppXManifest>
<Psf.Json>Config.Json file created and added to the ingredients.</Psf.Json>
<Psf.Json>Added to Json Application PsfLauncher1.exe</Psf.Json>
<Psf.Json>Added to Json Process exclusions for PsfLauncher and PowerShell.</Psf.Json>
<Psf.Json>Added to Json Process .* with MFRFixup.dll RegLegacyFixups.dll </Psf.Json>
<Psf.Json>Fix working directory and original shortcut to match.</Psf.Json>
<AppXManifest>Added InstalledLocationVirtualization to AppXManifest.</AppXManifest>
<AppXManifest>Removed desktop7:shortcut entry from AppXManifest for PsfLauncher1.exe</AppXManifest>
</FixApplied>
</FixesApplied>
 
<FinalPackage Description="The saved package had no remaining detectable issues that could not be resolved.">
<!– Information about the final package when saved by TMEditX. –>
<PackageStatistics NumberOfFiles=”121 NumberOfRegKeysAndValues=”416 HasPsf=”false/>
<Dependencies>
<Dependency Name=”Microsoft.WindowsAppRuntime.1.4 Publisher=”CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US MinVersion=”4000.1010.1349.0 MaxMajorVersionTested=””/>
</Dependencies>
</FinalPackage>


</AnalysisReport>

Where to get TMEditX

The latest version of TMEditX is found at the following link.  TMEditX has a fully functional trial mode that can be used to verify just how good it is.

TMEditX Download (tmurgent.com) 

By Tim Mangan

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