This blog explains the process of using junctions with App-V 5 to resolve application issues caused by hard-coded paths or path length limitations.
Using Junctions with App-V 5
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" & 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]