Updated solution to Paint.Net plugins in a connection group

Maybe Steve Thomas isn’t as crazy as he looks? I thought he went a little nuts when he wrote this blog post and suggested that you should always sequence using VFS. I mean, that is dead set against everything Microsoft has ever said. I did not disagree with the idea of VFS’ing things, but I have never said to VFS all of your packages. But now I’m not so sure he is all that crazy.

In February, I posted a solution to Paint.Net plugins delivered via App-V Connection Groups (https://www.tmurgent.com/TMBlog/?p=1913). It was ugly, but instructional for solving similar problems. In our second Eastern Europe class last month, a student (let’s call him ‘C’ since I don’t have permission to use his name) finished the lab early and tried one of the things that I had said wouldn’t work. With Success!

It seems that Microsoft made a change in the Hotfixes that makes Connection Groups easier, and perhaps we didn’t really understand the small print that came with the hotfix all that well.

Ok, first of all there probably is not a great reason to use Connection Groups with Paint.Net plugins. Just put them in the main package and be done with it. But paint.net demonstrates a different sub-style of locating plugins than is normally used by an app. The primary types are:

  • Registry Key Style Browser apps, for example (Internet Explorer and others) use a registry style integration. In this style, the application supports additional plug-ins in the form of dlls. The Plug-in typically may be located anywhere on the disk, but is registered by adding a registry entry under a known app-specific key. Normally, the value of the registry item is the full path to the dll file. At app startup, the app reads all of the registry items under that key and loads the dlls into its memory space. Registry style plug-ins generally work well with App-V and Connection Groups.
  • Folder Style In this style, the application supports additional plug-ins in the form of dlls also. The Plug-in, however, must be located in a known specific folder. The application might use a hard-coded path, or a registry based string to know the location of the folder, or it might use a relative path from the current working directory, or it might do what Paint.Net does. In this style, the app looks for dlls in this folder and loads them all into its memory space. Thanks to PVAD and VFS, these styles may or may not be troublesome for App-V Connection Groups.

In the Folder Style, installing the main app to the PVAD generally caused a problem, because while you can specify the same PVAD folder for the plug-in, the PVAD folders do not overlay. Instead, the PVAD is actually moved at the client based on GUIDS, and the different packages in the connection group will have different GUIDs, such that the plug-ins are never seen.

In the folder style, installing the main app to the VFS, and plug-ins to the same VFS area seems to work when the application locates the folder using a hard-coded path, or a registry string based location. When the application uses the current working directory of the application, by default this will be rewritten as the GUID path of the primary program, but we can manipulate the current working directory to the VFS location by manually manipulating the DynamicConfiguration.xml file, and this will work. Technically, this working directory doesn’t exist until the virtual environment is open, but you can specify a fictional working directory when you launch an application so Windows doesn’t care that it isn’t present until the app starts running.

But then there is the folder sub-style that Paint.Net uses. We can’t be sure exactly what the code does, but it appears to locate the location of the executable’s exe file (probably using a programming technique referred to as reflection). And in App-V, whether or not the app is VFS’d, this location will always result in a path under the App-V cache GUIDs of the package containing the EXE. Even when the primary package is VFS’d, this meant “AppV\Guid\Guid\Root\VFS\…”. So the plug-in would not normally be seen.

My previous trick was to think like the client. This involved sequencing the main app in the PVAD, and sequence the plug-in by first installing Paint.Net exactly like it would appear at the client (under AppV\Guid\Guid\Root), and then VFS install the plug-in.

What ‘C’ found, when sequencing using 5.0 SP2 with Hotfix 4 and testing on 5.0 SP2 client with Hotfix 5, was that he could VFS install Paint.net and then also VFS the plug-ins — and it worked. I know that this did not work in the original 5.0, and I am 95% sure that it did not work in 5.0 SP2 (since I posted this after the release of SP2). So it probably came in with one of the hot-fixes. So what changed?

Well, it appears that a further merging of the VFS has been added in the hotfixes, probably in Client Hotfix 5. In the past, the VFS paths only merged when the program tried to read from the overlayed location. So previously, with both packaged VFS’d, only if the app requested C:\Program Files\Paint.Net\Effects would the merged files be seen. Since the app requested “C:\ProgramData\AppV\Guid\Guid\Root\VFS\ProgramFilesX86\Paint.Net\Effects”, previously the app would only see the files of the package using those GUIDs. But now, it seems that a request to this folder is redirected to appear as the C:\Program Files\… counterpart where merging, not only with other packages in the Connection Group, but potentially with local (native) files when the parent folders are marked merge with local.

This change, along with the change to let you choose to allow the application to update data and setting files (but not executable components) located in the VFS, make it much more reasonable to sequence to the VFS.

But should you regularly sequence to the PVAD or VFS?

Microsoft Sequencing “Best Practices” say PVAD first, unless you have a problem.

Microsoft PFE MCS Steven Thomas (known as @MadVirtualizer on Twitter and “The Gladiator” when he blogs on TechNet), recently blogged that he is changing his mind and that perhaps you should always install to the VFS due to a rash of issues that he has resolved by changing a PVAD install to a VFS one. I am guessing that Steve’s post should have referenced that he assumed that you are using 5.0 SP2 HF5 (or above).

I am not sure yet whether this is a good “standard practice”. I do know, from my research papers on App-V 5.0 SP2 performance that there is a small, yet measurable, performance penalty to opening files in the VFS. I also know that I had issues with non-PVAD installs of certain apps in the past (at least before the fixes), and issues with other apps unless I VFS’d them. With App-V 4.x, I argued that VFS’d installs were generally OK and I usually defaulted to the practice unless it caused a problem. But in App-V 4.x I never found the reputed performance hit for VFS that I see in 5.0.

So I am not (yet) confident that VFS first is the wisest default, but whether you PVAD or VFS, I would recommend always starting with one, and change the practice on a per-app basis only if you encounter a problem. But stay tuned, we are sure to address this topic again as we learn more.

By Tim Mangan

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