What I Do: App-V 5 and the “Primary Virtual Application Directory”

If you have sequenced on App-V 5, you probably have wondered what to use for the “Primary Virtual Directory” (PVAD).

Me too. But in this blog post I will discuss what I know and what I do (currently).

Under the older versions of App-V, we called this the asset root folder, and all sorts of names, but in essence this folder is the location that sequencer is supposed to expect you to install the application into. During monitoring, files and folders added by the app installer under this folder are treated differently than those added elsewhere on the system.

Those outside this folder are VFS’d, meaning they are stored under a subfolder of the VFS folder in the package. The subfolder name is symbolic, a well known name that the client can use to match where the asset added. Previously, these symbolic names were mostly those CSIDL_ variables, but Microsoft deprecated the CSIDLs many years ago (Vista time frame, I think) so these are replaced by a set of new symbolic names. We have yet to find any Microsoft documentation listing the full set of these new names and where they map to, but at least the mapping is usually recognizable when you see one.

In the older App-V, files that were not VFSd appeared to the application to be exactly where you installed them to (at least when the virtual file system drive letter at the client matched that of the sequencer). This was critical to a number of apps in the early (SoftGrid) days as we were dealing with a lot of apps that wrote file location information into randomly named files.

You see, back then we were dealing with apps originally written for Windows 95 (or maybe even 3.11) that were ported to Windows NT and 2000. Apps that pre-dated the Windows Registry had no choice but to store configuration data In files. If the app used an ini file to store the data, the sequencer was smart enough to find and fix up those references. But if the developer decided to store it in a file of another extension, like .dat or .db, the sequencer didn’t go looking in there. So to make sure those apps worked we had to install into the root folder.

App-V 5 has removed the virtual drive letter, but it still asks for the PVAD. Microsoft has recommended that you should specify in this field the folder that the installer will install into. For most installers, this means some vendor and product folder name under the Program Files folder. I don’t know about you but unless I test install the app once, just to find exactly what name it uses, I don’t remember exactly what this will be.

So I have taken to using a different name for the PVAD. Along the way I’ve learned a few things…

When the sequencer monitoring begins, the sequencer will create the PVAD if it doesn’t exist. This is the same as for 4.6 SP1, except that for some reason it doesn’t bother creating the randomized “short name” for the folder. This was a “fix” Microsoft added so that we no longer needed to specify the root folder using a short (“8.3 compliant”) folder name. The reason for all of this short name shenanigans was that at t he client, each virtual package was mounted using this root folder’s name under the same drive letter. This meant that we needed to keep those root folder names unique (which was a PITA), but the real problem came if you used a long folder name. Before the sequencer created the randomized short name, each long name root folder would create a short name by taking the first 6 characters and appending a “~1” to the end. You always got a “~1” because it was created in an otherwise empty drive. But at the client when the packages are added to the common drive letter, if two packages had the same short name, the short name of the second to arrive would get modified to “~2”. This had a tendency to break apps with COM dlls as these are often registered using short names.

In App-V 5, they got rid of the randomized short name because the PVAD of each package is not mounted under a single common folder. Instead, we have the single common folder (C:\ProgramData\AppV) that has the Package GUID (which is already unique). Under this we find the Package Version GUID, and then a folder named “Root”. Root is the equivalent of the PVAD, and you will find any files you added to the PVAD in the sequencer right here. You will also find a VFS folder with non PVAD files under there.

With packages I have been creating, I have been specifying the PVAD by naming it to be a folder directly under the C:\ drive. Because I just entered the package name in the field above where you specify the PVAD, I copy the package name and use it for this folder name. So if the package name is “XXX_WinRar_Win7x86”, I use an asset folder named “C:\XXX_WinRar_Win7x86”. And this seems to work well, whether or not I install the app into this folder, or let it VFS.

But when you go into the virtual environment of the package on a client, using either the Windows Explorer or a cmd prompt, and look at the root of C:\, you won’t see the C:\XXX_WinRar_Win7x86 folder. You can see this in the image below.

The explorer window has all of the “hide” options I can find disabled, and it is running inside the virtual environment of the package. At first, I thought that this would break a whole lot of applications with buried file path references. But it didn’t. When I queried Microsoft contacts about this, they seemed to believe that the applications have improved over the years and no longer stored path information that way and it wasn’t an issue any more. I had my suspicions about that, beginning a “search for the app broken by App-V 5”. I didn’t find one (but I now know why, as I’ll explain later).

When I noticed that the PVAD wasn’t seen at the client, and knowing that the mounting method removed the uniqueness issue, I began some tests where I sequenced every package to the same PVAD. This actually worked, however I still do not recommend it because I expect there to be some issues if you later add the two packages into a single connection group.

So I started to think (incorrectly) that because the app didn’t see the original folder, that I would be better off installing to anywhere except the folder I specify. You see, all of those VFSd folders do show they files under their originally installed locations when inside the virtual environment. I can browse to C:\Program Files and see the “Adobe” folder right were I (and the app) expected it to be. So if there was a hidden file reference, it would work only if I installed outside the PVAD. But I was wrong.

Last week, when I was debugging a package and found out something new. The client does have a back door that presents the PVAD folder name to the application inside the virtual environment. The folder is not displayed when you enumerate the parent folder, but if you type in the name, it works! The image below is the same Windows Explorer window after I type the folder name in by hand.

It isn’t hidden in the traditional ways (using the hidden attribute or system folder attribute), so I don’t know how they did it. It acts as if it is a super-secret-hidden symbolic link folder to the root folder under ProgramData. But if the application asks for a file under the PVAD folder using the original reference, it will get that file! This is probably why my search for the broken app has been futile so far.

So what does this all mean to how I select the PVAD?

  • I want each PVAD to be unique. This is because apps might try to reference it, and if I added two packages with the same root folder into a connection group I’m pretty sure that there would be an issue on which package the hidden lnk would link to. I know others have suggested just using “C:\” for the PVAD, but I suspect this is asking for trouble somewhere
  • I continue to use the C:\[PackageName] method. This is because it is easy to do and I know it will be unique per package.
  • While I’m sure that someone from Microsoft would probably disagree with me, I don’t really care if the app installs into the PVAD or not. Being lazy, I’ve been letting them install outside the PVAD, and haven’t been having problems so far.

By Tim Mangan

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