Friday, November 27, 2015

AppV5 - When Application Compatibility Toolkit doesn't work

I have an application that embeds an IE window and generates a small HTML file for some content.  This application has some.....   interesting....  configuration settings that require a folder with "EVERYONE:F" permissions.  This folder cannot be in a path that contains spaces, cannot be a environment variable and the vendor recommends to put the folder on the root of the C: drive as C:\TMP.  To make it more crazy, when launching the application it will generate a folder under the C:\TMP that is locked to the %CLIENTNAME% (e.g., C:\TMP\ComputerName) and every login to the application generates unique files to that session, so technically, each folder underneath TMP is unique to the user.  The vendor actually recommends completely deleting the contents of the TMP folder DAILY.

So why not just store these files in %TEMP% instead?  Great question.  If the vendor made that happen I wouldn't have this lovely blog post.

(Just for a note this application utilized multiple folders on the root of C: as well, TMP being one, since we move our PackageInstallationRoot to a different drive, TMP isn't available on C:)

With that all said, what am I looking to solve?

Well, I don't want to be creating folders on the root of the C: drive as this application will be on our 'generic' PVS Citrix servers and minimizing the potential for pollution on the master image is a goal, having to create a folder and configure permissions is possible and I've done it before but it's not very clean or elegant; really if we're going to do that then we may as well pollute the C: drive.  We want to maintain portability so creating a C:\TMP folder on the master image prevents us from publishing this package on desktops or other systems in the future unless this is well documented requirement.

We've just learned a new trick though, we can try using Microsoft ACT to create a file path shim that redirects the path to a different one.  So let's do that...

The problem.
 I created the shim using the steps from this post.  (C:\TMP;C:\ProgramData\Microsoft\AppV\Client\Integration\D8E3DB68-4E48-4409-8E95-4354CC6E664B\Root\VFS\ProgramFilesX64\dlc11.2\TMP) I then launched the application and...

Huh.  That doesn't look right.
And it didn't work.  I then used procmon.exe to examine to see if it was reading the file correctly:
I see SUCCESS...
Procmon.exe is reporting that it IS reading that HTM file correctly.  So why isn't it being displayed?

I ran across a similar issue on another application and what I found was that the embedded component appears to be running *outside* the bubble.  Since the shim targets applications (in this case prowin32.exe) all reads from prowin32.exe are being redirected by other processes are not.  I suspect (though I have no proof), in this case, that somehow the IE component is breaking outside the bubble and so it's NOT getting redirected.

Can we force all programs to get redirected to the proper path?  Yes, we can.

Using symbolic links we can force any access to the directory to be redirected to the AppV package path.  AppV will then see this is a path within the 'bubble' and redirect *again* to your local profile where the AppV5 writes will take place.

I removed the shim and then executed:
Symbolic Link
mklink /d C:\TMP C:\ProgramData\Microsoft\AppV\Client\Integration\D8E3DB68-4E48-4409-8E95-4354CC6E664B\Root\VFS\ProgramFilesX64\dlc11.2\TMP

Tracing with procmon.exe now showed us this:



And the application now displayed this:

So the application is now working without any issues, all of these 'temp' files are being redirected to a location where they will not be saved between sessions so no cleanup is ever needed.  We need to add the mklink.exe to the DeploymentConfig.xml.



AHS-BDMPHARMACY-PREFLIGHT.CMD:

And we are now done.

Thursday, November 26, 2015

AppV5 - Using Application Compatibility Toolkit to solve issues

We have several applications that install folders in the root of the C:\ drive.  For most AppV5 implementations, this wouldn't be an issue but we modify our PackageInstallationRoot folder so the token {AppVPackageDrive} turns into the drive letter specified in the PackageInstallationRoot registry key.  For us, that's the D:\ drive.  This causes an issue because when you sequence an application to C:\ the application has an expectation for it to be there.  Ideally, AppV takes care of that by the use of the tokens, but this breaks down when applications are hardcoded.

So far, we've been able to work around these issues by using junctions or setting the PVAD to the folder as the PVAD acts literally on the value specified, essentially becoming a hard coded, custom, token.

But now we have an application with THREE folders that are installed on the root of the C:\ and the application is hard-coded to look for two of them.

Hello my nemesis's


If we do nothing this is the error we get after attempting to login to the program:


Looking at the appvve we can see the D:\ is coming up with those folders.


So this isn't going to work.  How can we make it work?


After publishing this application on the server, we install ACT on the Citrix server.


Launch the "Compatibility Administrator (32-bit)"

Right-click on "New Database" and select "Create New > Application Fix"


Enter the details and browse to the application and click "Next"


Click 'Next' on the Compatibility Mode screen


Select 'CorrectFilePaths' and then click 'Parameters'


In command line, enter the path that should exist, then a semi-colon divider ";" and then the target path:
C:\webforms;C:\ProgramData\Microsoft\AppV\Client\Integration\A3E3C00D-19F1-47CB-9BA1-464DB85DC3CA\Root\VFS\AppVPackageDrive\webforms
and click "OK"

Try a Test Run.

And the application launches without any error messages!

Click 'Next'

Then Finish.

Click 'Save' then name your database and click "OK":


Save your fix now:


At this stage you now need to put your SDB file somewhere accessible for when the package is published.  We put it on a fileshare.

Now, all we need to is install the fix.

Since we publish our application globally, I added the fix to the DeploymentConfig.xml:


And we are done! The application now works.