App-V 5, Junctions and Path Length Limitations

I was migrating an old application recently which launched Macromedia Director.  It launched fine during sequencing and when installed locally, but when I ran the App-V 5 version i saw the error message:

Unable to load movie playlist. Does the .INI file exist? It must contain a section ‘[Movies]’ with an entry ‘Movie01=Pathname.dir’.

To cut a story short, it turns out the when App-V mounts the application to a path such as C:\ProgramData\App-V\[PackageGUID]\[VersionGUID]\Root\Vocal Pathology_1\Vocal Pathology_I.exe  the path name becomes too long and exceeds the character limit of 127 characters!  See here.

The only way I could think of resolving this via an App-V package would be to spoof it by using a symbolic link, or more specifically a ‘junction’.

Both symbolic links and junctions essentially link one location to another location.  But creating a junction seemed like a better option according to this post on SuperUser – I particularly liked the way that remote users could access the junction from a remote computer.

Our task then, was to create a short path junction that would link to the longer path used by App-V.

When creating a junction on the command line, the syntax is:

mklink /J "[Non Existing Junction Full Path]" "[Existing App-V Full Path]"

It’s important to note that where you are linking from should NOT exist when you run this command, and where you are linking to SHOULD exist. 

We will create a junction with the path of C:\VocalPathology after the package is added (hence at publish time) so that the target path exists, and for cleanliness we will also remove the junction at the time of un-publishing the app.

In the UserConfig.xml file (my apps are published to users and not machines) I added the following code – note that I first rename C:\VocalPathology if it already exists (otherwise creating a junction will fail), then create the junction.  Also note that the token [{AppVPackageRoot}] ultimately resolves to C:\ProgramData\App-V\[PackageGUID]\[VersionGUID]\Root and that our target executable lives in a sub folder of the package root called ‘Vocal Pathology_1’.
.

<UserScripts>
	<PublishPackage>
		<Path>cmd.exe</Path>
		<Arguments>/c move /Y "C:\VocalPathology" "C:\VocalPathology.old" &amp; mklink /J "C:\VocalPathology\" "[{AppVPackageRoot}]\Vocal Pathology_1\"</Arguments>
		<Wait RollbackOnError="false" Timeout="30"/>  		
	</PublishPackage> 		
	<UnpublishPackage>
		<Path>cmd.exe</Path>
		<Arguments>/c rmdir "C:\VocalPathology\"</Arguments> 
		<Wait RollbackOnError="false" Timeout="30"/>  		
	</UnpublishPackage>
</UserScripts>

Now that we have created the junction, we need to amend where the shortcut points to in our UserConfig file! Find the <Shortcuts> section and amend the <Target> element.  Beforehand it points to the the full App-V location since it uses [{AppVPackageRoot}]:

<Target>[{AppVPackageRoot}]\Vocal Pathology_1\Vocal Pathology_I.exe</Target>

But we will need to hard-code the shortcut to point to our junction (shorter path) instead. The new shortcut will be:

<Target>C:\VocalPathology\Vocal Pathology_I.exe</Target>

When the package gets published, the shortcut will get ‘sucked’ into the virtual file system since App-V will append the /appvve parameter like so:

"C:\VocalPathology\Vocal Pathology_I.exe" /appvve:[PackageGUID]_[VersionGUID]