Tag Archives: Sequencing

App-V 5 and App Related Data

One of the big benefits of App-V has always been that applications that needed certain kinds of remediation to work today were automatically dealt with.

I’m talking about apps that were developed without complete support for multiple users (or multiple tenants), or for apps that assumed systems that have no security protection to write to common locations.

We just sequenced them, and App-V automatically redirected any writes by the user to a safe location isolated to only that app. And it all roamed with the user.

Until version 5.0, where Microsoft decided that virtualized apps should behave more like non-virtualized apps. For the most part, the changes in 5.0 are welcome and make the job of preparing and distributing apps easier. But not for a log of older apps.

Primarily we are talking apps that were originally developed before UAC in Windows Vista, but also apps originally developed before people understood multi-user in Windows XP. These categories, unfortunately, include a whole lot of business apps developed by enterprises themselves. And in most cases the enterprise cannot update the app. Reasons for being unable include:

  • No longer knowing where the source code is
  • Developer is no longer at the company
  • Don’t have the tools to even rebuild that old code
  • Nobody wants to take ownership of it

In App-V 5, we really have a couple of big problems with these apps:

  • The virtual app doesn’t roam all of the changes made by the user (the ARD).
  • The app won’t work because of file or registry writes that now fail

You would still have those problems with a natively installed version, so App-V 5 isn’t breaking anything that way, but usually these apps worked great in App-V before.

A while back, I created a tool (AppRemediation) to take care of much of the first issue. I continue to find more things and need to update that tool at some point; it doesn’t get 100%.

So to better understand the problem, I performed some new testing. The accompanying chart shows the results of all of that testing.


Click for a larger image

Testing was done using a new version of my home-built AppVPersonalization tool that allows you to write to specific places and see if it works, or where the data is being written.

The testing consisted of making a package with files, registry items, and environment variables of different kinds inside the package. I tested both cases of having the program be located inside the PVAD folder and not (VFS’d). I also tested as an admin or standard user, and with the program elevated to a different admin user using RunAsAdministrator. The chart above shows what happens in the different scenarios.

I am hoping that Microsoft will continue to adapt the App-V product to improve it’s ability to make virtual applications easier for these older applications. If not, at least you know a little more about what to look out for.

AppV is Hot Now

Microsoft App-V seems incredibly hot right now, with everyone getting ready to jump on App-V 5 when SP2 comes out. There is way more activity in this space than I have ever seen!

 

I have been running training classes on App-V for over six years now. Back when Microsoft bought Softricity, I saw an interest spike. But it was not a big spike, and it did not last long. I also have been seeing a somewhat larger boost in interest in the last 2+ years as customers started on their Windows 7 Migration, a boost that has continued through this year. That boost has caused me to add an extra class into the schedule each year, and those classes have been mostly full.

But in all of that time I never booked a student for a class until after the previous class had completed. Until now. This summer it has been hot. We have a class starting next week in Boston. Full. The next class is in Phoenix in December. Full. I added a new class today in January through our partner in Phoenix (ThinClient Computing). It already has students booked. What is going on?

Companies that use App-V 4.6 are ready to move over to 5.0. Companies that use Citrix Streaming for App Virtualization (which is going away) are switching over to App-V. Companies that never used App-V and are now a tad late in their Windows 7 Migration are using it to get done faster. Companies that completed an overhaul to SCCM2012 are now ready to virtualize their apps. Companies that finished their Migrations are virtualizing apps for flexibility. It is like a huge wave hitting us right now.

And finally there is what Microsoft is doing to the product. App-V 5 is a complete rewrite of the application virtualization stack; modernizing what AppVirt is all about and trying to make it simpler. While I have recommended App-V 5 for new customers, I have been cautious with existing customers thinking about upgrading to version 5 until we see a number of new issues resolved and other new things that we had been asking for. Most of these should be solved with the release of SP2, although I am still cautious about how well it will perform. . But the customer interest tells me that they are ready commit to SP2 now, before we even see the final bits.

App-V is finally hot.

App_Remediation: New Tool for App-V 5 apps in Roaming Environs

App_Remediation is a new free tool I am releasing to the public today.

App_Remediation is a console application designed to be used with App-V 5 (and above) to save and restore application related data (ARD) between locations that normally do not roam and those that do.

App-V now isolates ARD changes and redirects the saved file changes to locations that either roam or not, based on whether those changes would have roamed if the application was natively installed. This is quite different from the versions of App-V before version 5, where these changes would have been isolated and redirected to a location that always roamed. This remediation of badly constructed apps is very important to customers in a roaming environment, including not only those using “roaming profiles”, but also if using folder redirection, home drives, or other methods.

This program can be used in scripts to remediate virtual applications in two different ways:

  • PER APP BASIS
    Quite possibly, you only have a few apps in production today that require this kind of remediation. A simple solution would be to add this program as the script file for both “StartVirtualEnvironment” and “TerminateVirtualEnvironment”.

    For the StartVirtualEnvironment script, you use the parameter “/restore“, followed by a space, and then followed by the Package Id GUID (not the package version guid, and not inclosed in { } characters). You would mark the script to start outside the virtual environment with rollback=false.

    For the TerminateVirtualEnvironment script, use the parameter “/save“, followed by a space, and then followed by the Package Id GUID.

  • PER USER SESSION BASIS
    The app may also be run as part of user logon / logoff scripts, using the “/saveall” and “/restoreall” parameters. No GUIDs required as it will save or restore all packages found.

HOW IT WORKS

When saving changes, it will copy the folders and files (preserving the attributes, ACLs, and timestamps) from the users AppData/Local redirection repositories into a similar location under the users AppData/roaming location.

For example:
    C:\Users\Tim\AppData\local\Microsoft\AppV\Client\VFS\7EA4C0C9-2099-E743-AAEA-A1C03D11138E
is saved to:
    C:\Users\Tim\AppData\remote\Microsoft\AppV\Client\VFS\SavedFromLocal\7EA4C0C9-2099-E743-AAEA-A1C03D11138E

The program does not touch isolated registry information, as those are properly handled for standard users when apps do not require elevation.

Example Script

Below is an example of use of App_Remediation solving the problem of Paint.Net saving user settings into AppData/Local based files. The Package Id GUID is conveniently found at the top of the Deployment or User config file as PackageId=…

<UserScripts>

    <StartVirtualEnvironment RunInVirtualEnvironment=”false”>
        <Path>C:\Windows\App_Remediation.exe</Path>
        <Arguments>/restore 26ceb0bc-1e69-4de1-a444-70b6f1e0dfc3</Arguments>
        <Wait RollbackOnError=”false” Timeout=”30″/>
    </StartVirtualEnvironment>

    <TerminateVirtualEnvironment>
        <Path>C:\Windows\App_Remediation.exe</Path>
        <Arguments>/save 26ceb0bc-1e69-4de1-a444-70b6f1e0dfc3</Arguments>
        <Wait RollbackOnError=”false” Timeout=”30″/>
    </TerminateVirtualEnvironment>

</UserScripts>

You can also solve this problem with some User Environment Management products, although ironically not Microsoft’s UE-V product. This tool should prove to be easier to use, since you don’t need to worry about the app-specific details of what to capture or not. Just use this and it grabs everything that App-V isolates.

See this page for more information on download and installation.

The return of the Duplicate Package ID in App-V 5

It haunts me still! In every release of App-V since 4.0 there has been a new and unique way to generate apps with duplicate GUIDS. I have blogged about this both here and here. Granted, each time it was a case of wanting to be efficient with MY time and it was solved by careful setup of my snapshots. But I was hoping that we were past all that with version 5.

It’s baaaaaaaaaack!

Quick technical primer stuff.

A GUID, which is an acronym for a Globally Unique IDentifier, is generated on demand by a Microsoft library function when code wants one. This 32 character identifier uses 16 letters in each position, allowing for the generation of 16**32 possible values, which is over 340000000000000000000000000000000000000 values. To make it globally unique, no matter when or where it is generated, the algorithm uses both time and local hardware-ish information to create the seed to generate the random number. The problem is that seed is generated at boot time. The “randomization” isn’t all that random. Once the seed is set, the next GUID generated by that seed is fixed. Generating a random number changes the seed again, so the following GUID request would be random again.

When you take a VM snapshot with the OS running, you freeze the current seed. So if you revert the image, and quickly generate a new GUID (before anything else on the system generates one), you will get the same GUID when you revert and quickly do it again.

While the App-V team could solve this in the sequencer by re-priming the pump before asking for a GUID the first time, they still don’t get it. So I have moved to a practice of always making my snapshots with the OS shut down to make sure that I can’t generate a duplicate package GUID. Well, almost always…

How I did it in App-V 5

I was sequencing Paint.Net and wanted to use Connection Groups to bring in the various plugins as separate packages.

My base sequencer image was correctly created, meaning the snapshot was taken with the OS shut down.

But Paint.Net has a VC runtime dependency that needs to be installed prior to it’s installation. Knowing that I was going to do a lot of packaging with that dependency, I installed the dependency, copied down all of the installers for the program and all of the plug-ins to the desktop, and took a snapshot. Wanting to work fast, I didn’t log out or shutdown the OS, I took the shortcut of snapping it while logged in. Good thing I don’t have a CSO to report to.

So I sequence Paint.Net. I revert. And then for each of the 10 plug-ins I revert and then sequence the plug-in using the “expand to local system” option for the base package.

I then go to my test client and (using my AppV_Manage tool) click on the packages to add and publish them. I didn’t even get to the point of making the connection group. I had a big problem. I could add all of the packages. But sometimes when I publish one, it un-publishes a bunch of the others. But not all of them.

For example, when I published the MadJik effect plugin, shown below:

If would un-publish the EffectsV38 plugin:

If you look close at those two packages, you can see the duplicate GUID in the PackageID. Each as a unique VersionID (indicating that the sequencer must request the PackageID first, which re-primes the pump.

So why didn’t all of the packages have the same PackageID? Pure luck and timing. I had to start the sequencer quick enough after the revert to beat out other background “system things” that also generate GUIDs.

In App-V, the client uses a duplicate package ID as an indication of packages that are different versions of each other. Prior to App-V 5, the client also looked at the package name also. If two packages had the same PackageID, but different PackageNames, it generated an error about a duplicate GUID. App-V 5 works differently, so no obvious error, just a little frustration until you figure out what is going on.

App-V 5 notices the duplicate GUID and assumes that these must be different versions of the same base package. Because both of the packages are Version “0.0.0.1″, I am guessing that the client couldn’t determine which of the two was the newer update package, so whichever VersionID gets published last wins, bumping out the other one.

Conclusion

Another release, another manifestation of the problem. If you never take shortcuts with your snapshots, or just take a long. sloooooooooow, sip of your favorite beverage before launching the sequencer, you should be OK.

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.

About my Toolbelt and “The Secret App-V 5 Client Debug Logs”

There is nothing like a good set of tools ready when you have a repair project to do. But too many tools are distracting.

Working with App-V 5 through all of the pre-releases and now the final release for some time, I have settled on my three favorite tools. And it is time to let you in on the secret.

The Screwdriver

The screwdriver is the most handy of the tools. It is the one always just there, sitting right on the workbench where you need it. I don’t have to go looking for it. For me, my screwdriver for working with App-V 5 is the Windows event logs. Nothing to go get. Just pop open the event viewer that is already part of the OS and you can see what is going on.

Microsoft has toned down the cryptic error codes and messages presented to end users in 5.0. Previously, I could have a pretty good idea what is going wrong just be seeing the error message. Well, maybe plus a little googling or my Failure to Launch tool. But in the new release, the error messages are fewer and less informative to me (not that the old messages were informative to end-users).

So in 5.0, the Event viewer is my screwdriver. but don’t go looking in the Application log. In this release, Microsoft has segregated out the App-V logs into their own space.
Look down to the “Applications and Services Logs”, pry that open, and then pop open the Microsoft folder and find the new App-V event logs.

As you can see, there are three separate logs for the App-V Client. The good stuff, meaning the errors that you are probably looking for, go into the Admin log. The Operational log is more verbose and gives you a better idea of what the client is doing and when, but most of those messages are informative things like “I’m streaming something”. I usually look in the Operational log only if the Admin log didn’t provide enough detail.

The intriguing sounding Virtual Applications log is usually empty. By usually, I mean that I have never, ever, seen a logged message in there and I am unaware of anyone who has.
With some digging, I discovered that there are four messages that can be written to the log, and they seem to deal with special VFS errors that might prevent an app from launching. But I’ve never seen them, not even with the VFS problem this week that caused me to go looking for my tool belt.

The Side Story

I have this app I wrote. I write a lot of my own little tools, some that end up in the tools section of the TMurgent website, but also a lot that don’t. Often, such as the case with this tool, the tool is special built to do just one thing. Usually not a very exciting thing, but to do just that one thing. These tools are like those surgical instruments they slide into a vein with a camera to go look at something. The purpose of this tool isn’t important, but it was written to clearly identify what App-V would do when an app did this one particular thing. So I sequenced and ran it in the client to see. The tool worked as planned, and I documented the results in our training “companion guide” to explain how the client works.

But then I gave that section of the doc to my daughter Kate for verification. Kate graduated from college last year and has joined the company, mostly as part of our custom sequencing service, but sometimes doing projects like helping me on this project, or co-writing our book PowerShell with App-V 5. Any way, she sequenced and ran the app, but came up with an error dialog that hadn’t happened for me.

When she launched the virtualized app on the client, this error message would pop up. The application required elevation, and this would pop up just before the prompt for credentials. After entering credentials, if you just click the button to close the dialog, the app then worked as it was supposed to. As you can see, the error dialog is not terribly informative (can’t give end-users useful information now, can we?). So I pulled out the ever present screwdriver and looked into the new App-V logs in the Event Viewer.

They weren’t much help in this case, pretty much letting me know what I already knew. Something was wrong, and maybe the VFS was involved.

The Hammer

When the screwdriver doesn’t work, I usually go looking for the hammer. It usually isn’t sitting on the workbench (the VM I’m working on), but hanging at arms length on the wall. Or in this case a file share. For me, the hammer is Procmon. If there is an environmental problem the hammer can usually beat it into submission.

But as I looked at the hammer, it just didn’t feel right to me today. I don’t know why, but I decided to abuse the screwdriver already in my hand.

You see, just the day before, I had noticed something in the Event Viewer when looking at an XenApp issue unrelated to any of this that I hadn’t noticed before. The event viewer has an item under the View menu to show additional logs.

 

The Secret Debug Logs revealed

So I pried off that lid with my handy screwdriver, and looked down to the App-V logs. Wow!


Microsoft has provided a ton of very specific debug logs for App-V. Each of those additional folders you see have a single debug log under them. These debug logs are disabled, by default, but we can turn them on when we need to.

A Side Note about Eventing, Debug Logs, and Performance

When you right click on one of those Debug logs you can enable the log file. But you get a warning that doing so might cause events to be dropped. Ignore that. I mean, you wouldn’t want to leave any of these logs enabled in production, but you aren’t going to have a problem enabling these for a test.

The Microsoft App-V client, like all of the rest of the Microsoft (and many ISV) software, are constantly sending a stream of messages using a facility of the OS known as “Event Tracing for Windows”, or ETW for short. ETW is a highly efficient facility. A process running in user mode queues up a message and calls a utility. The utility context switches to the kernel and deposits the message in a queue, without any processing, and returns to the running process.

Sometime later, a kernel thread will wake up and process the queued up messages. Any software running on the OS can register with ETW to receive certain messages. The event viewer is the primary facility that registers for some of these messages. But normally it only registers for a small percentage of the message categories that exist. And any messages that are not registered for just require freeing the memory when this kernel thread wakes up.

To summarize, all of this logging, determining that nobody is listening, and discarding of ETW messages is always going inside the OS today already.

The Reciprocating Saw

Which brings up the other tool in the workshop, the Reciprocating Saw. This is the most powerful of tools, capable of taking down a house. I’ve owned one of these for 25 years and probably only used it a handful of times. In Windows, when the hammer won’t do, I pull out XPerf. XPerf lets me register for any and all ETW messages, log them and then pour through the details in a very well designed user interface. I didn’t need to pull out XPerf today, but when you need a really powerful tool, go looking for this one.

So back to the no-longer Secret Debug logs and my problem.

So all enabling one of these secret debug logs does is to register certain messages to be sent to the event viewer log file. If the developer was sending thousands of messages per second towards a log file, enabling the log could have a significant performance impact. Thus the warning. But so far, I haven’t seen that effect with the App-V Client Debug logs that I have enabled.

Since the error message to the user, and standard App-V error log info, hinted at maybe a network or VFS problem, I wanted to look at logs related to those areas. Because the app worked for me, I decided to focus on VFS, and enabled (amongst a few others), the “Subsystem-VFS” Debug log. Tried the app. Refreshed the Event Viewer app to see if anything appeared. The message that was in the log then showed me right where the problem was. All with using just a handy screwdriver!

The Problem Revealed

My lab setup primarily uses local profiles. But I do have a couple of test user accounts in the domain that were set up for some roaming profile / folder redirection testing a few weeks back. And from this message I immediately knew that Kate had logged in using one of those accounts. The error, it turned out was a combination of the app elevating and permission settings in the remote home drive!

I probably would have found this if I pulled out Procmon, but this was way faster than sifting through a ton of unimportant events.

So now the secret of the secret App-V 5 client debug logs is out. Have fun with it!

The Case of the Missing Shell Extension (a Novel)

One the big mysteries to me has always been why Shell Extensions are so hard for application virtualization. And I had never really taken a deep look into them to unravel they mystery until this year. But now I have, and it turns out to be less of a mystery novel and more of the Steven King kind.

The Problem

The problem, in a nutshell, is that we use application virtualization to isolate out applications from each other and the operating system. But we need to provide interfaces that are external to the package so that the user can interact with the application, and sometimes so that other applications can interact as well. Typically, this means shortcuts to the start menu, so that the user can launch the applications, and file type associations so that the user can launch the application from a file of certain file types.

But over the many years of application development for the Microsoft platforms, Microsoft has offered developers many other types of integrations, especially with the windows shell, aka “the windows explorer”. Because of the isolation that App-V has provided in the past, some of those integrations worked and some didn’t. When they didn’t work, the integrations just don’t show up, and 99% of the time we can live with it because the functionality is still available if the user just launches the app. In the past we (improperly) called these things shell extensions and never understood why they were so hard to get right.

The Goal

With App-V 5 out, I wanted to see if I could use post-sequencing customization of the App-V package to deliver the missing shell extensions. We have already noticed that just by sequencing packages in App-V 5 that we had sequenced in the past, we are automatically finding that some of these missing integrations now appear in the new virtualized packages, but not that many more.

The Research

As a developer, I have never created shell extensions, so this has been a lacking area of my developer knowledge. So I went digging through the Microsoft documentation to learn more. It does turn out that Microsoft has very little documentation on Shell integrations written for IT folks. Almost all of it is aimed at the developer in MSDN, explaining how to create one certain kind of integration. They never really explain how the shell is supposed to work in complete detail. So after a fair amount of research over the last few months, let me try to provide a simplified definition of how the shell works in IT terms.

About Terminology

So first of all, let’s get our terminology right. Fourterms to talk about. “The Shell“, “Shell-Integrations“, “Built-in Shell Integrations“, and “Shell Extensions“. These will be defined as we go along, but you need to keep them straight.

The Shell

The operating system provides a replaceable and configurable “shell” which is the user interface presented to the user, what we sometimes call “the desktop”. By default, this shell is a copy of the Windows Explorer (explorer.exe) that is launched at the user’s login. By the way, vendors can, and have, provided replacement programs for an alternate shell, but let’s ignore that.

Shell Integrations

The Windows Explorer, out of the box, understands how to display the start menu and file and folder displays. It understands what to do when a user right clicks on a file, double clicks on a file, drags a file somewhere else, and drops it. And a countless list of other things. These default settings are available for any file or folder by default, and provide generic copy/move operations, unless the shell is configured for specific cases.

But the Windows Explorer is configurable in these actions. Especially when it comes to files that have particular file type extensions. We should call this file type associated configuration “shell integrations” as a high level term. So far, I have discovered almost two dozen kinds of configurable and/or programmable shell integrations. But generally we should categorize them as either with support built into the explorer itself, or external extensions.

Built-in Shell Integrations

The Windows Explorer has built-in shell integration support that allows for configuration of the icon display, default action, and right click menus, based on the file extension type. By built-in, I mean that only code that is part of the Windows explorer, as configured by information in the registry is needed, with two exceptions:

  • One exception is that for the icon display, the registry will contain a reference to either an icon file, or a file containing an icon; but otherwise it is completely inside the registry. Because the file reference might be inside the isolated package, previously App-V solved this problem by providing an external icon file for this registry configuration. In App-V 5, it actually points to the package file, but the “Publishing Feature Block” of the new AppV file format makes the icon portion of the file available externally.
  • These built-in shell integrations may also reference an target executable file (exe) to run, along with command line arguments, when the user requests certain actions. These are always exe files, and they work great with App-V because the virtualization engine knows how to start the executable inside the correct virtualization environment.

Windows pre-configures support for many files types for applications when you install the operating system. For example, a file ending in “.txt” is configured to work with Notepad.exe, and “.rtf” for Wordpad.exe.

The most obvious integrations are the icon displayed for the file, the double click action, and right click menu; but there are a few more specialized ones that we don’t need to go into detail on here.

There are also a few other pre-configured special cases, like for a mounted drive, or a directory. The latter is how an app can integrate a menu item when you right click on a folder or open area (which is a folder also), such as to create a new zip file.

The configuration for file associations is stored in the “classes” portion of the Windows Registry. Feel free to pop open regedit as you read through this (just don’t change anything!). The ones that apply to all users are stored under HKEY_LOCAL_MACHINE\SOFTWARE\classes, and ones that apply only to a specific user live in the HKEY_CURRENT_USER\Software\Classes area. Microsoft makes it easy for explorer by exposing an overlay hive called “HKEY_CLASSES_ROOT” which automatically combines these. Under the classes key, are subkeys for three kinds of things that explorer uses for configuration: File Extension Types (such as “.txt”), ProgIDs, and COM Guids.

The ProgIds you can think of as a link. An application might support multiple file types (.bmp, .png, etc), and can have each point to a shared ProgId that contains the detail.

Under the File Extension (or ProgId) there can be subkeys that are called “verbs”. These verbs are somewhat standardized by practice; words such as “open”, “edit”, or “play”. When a verb is configured with a shell command, it will appear in the right click menu and if the user selects the menu item, the registered target application is launched.

To complicate things, there can also be two special keys, “Open with” and “Open with ProgIDs”, which are further links, so that the user sees the “open with” menu with another program they can launch.

Shell Extensions

There can also be another subkey, called “ShellEx”. It is only the things under this key that we should refer to as “Shell Extensions“. Shell Extensions enhance the integrations available by allowing the explorer shell to load dll assets of an application directly into the explorer.exe for execution.

The way that this works, is that the registration will point to a COM based dll that has specific COM functionality for a Shell Extension. Now there are many kinds of COM objects, and most of them have nothing to do with shell extensions. These are a specific subset of the COM objects that the application might contain. Specifically, these COM objects must be “in-process” COM objects (so that the shell can load them directly into the explorer memory space for execution), and will provide the functionality using one of many specifically named interfaces (like “IContextMenu”) for the type of shell extension functionality.

The Prototype

At TMurgent we (Patrick and I) have been working on a generic technique to post modify application packages produced by App-V 5 and provide the missing Shell Integrations to teach in our training classes. We have a process down and it works really well.

When it works. But sometimes things go bump in the night and we still don’t get the extension. Which leads us to out story…

The Case of the Missing Shell Extension

The main character of our story is Techsmith Camtasia Studio. While a complicated application, it virtualizes quite easy and I use the virtualized version to produce videos all the time. But it has one small shell extension. I live without it, because I never would have known it was there unless App-V alerted me that it wasn’t supported.

The shell extension adds a context menu to the right click of files that end in “.camrec”. A camrec file is the raw output of a captured Camtasia recording. Normally, I just import this file into the Camtasia editor and work with it there. But now I know that if I right click on the file, this shell extension will examine the file and let me extract out the embedded avi or audio files directly from the Windows Explorer. Believe me, I can live without that. But I wanted to make it work because I thought I could.

So we used our process to post-modify the sequencer output, but this time the menu didn’t show up. The good news with the process we are using is that it doesn’t seem to break things, you just don’t get the integration you were looking for.

The Investigation into the Missing

CHAPTER 1: The Backstory

Our post sequencing technique tricks the publishing action of the App-v client to integrate the missing shell integrations, including Shell Extensions that are registered under the ShellEx subkey.

CHAPTER 2: Someone is Missing

Camtasia registers a Shell Extension that adds a ContextMenu COM object, and our process accommodates that. The idea of a ContextMenu type of Shell Extension is that when the user right clicks, the shell will call through iContextMenu function of this ComObject to determine if there are additional menu items to add (along with what to call if the user selects it). So the function supplied looks inside the file and adds any appropriate menu items.

CHAPTER 3: The Detective Arrives at the Scene

When this didn’t work, I pulled out ProcessMonitor to watch the shell (fail to) perform this trick. Using procmon, I could see explorer reading my neatly placed shell extension and properly opening the COM dll.

CHAPTER 4: A Strange Clue is Fount

But then I noticed two funny things.

First, it tried to open the registry for the HKLM based Camtasia Studio.

And then it tried to load an additional Camtasia dll. Both of these are part of the virtual application, but neither appear in any part of the shell registration, even on a natively installed copy.

CHAPTER 5: Deductive Reasoning Solves the Case

It seems that the COM dll has a hard coded string to open the Camtasia registry to determine what folder Camtasia is installed to. It uses this to locate the additional dll.

In App-V 5, the virtual files are available outside the virtual environment, just off in a strange place that is shielded from normal view. But the virtual registry is not. Our process can handle getting the right file reference when we add entries into the classes area, but it can’t make the virtual registry appear.

Since the COM dll running inside of explorer couldn’t open the registry location that was only inside the virtual registry, it didn’t know where to find the dll. So it checked in the explorer’s current working directory at the root of the C: drive. (It didn’t even do a path walk, which is typical behavior for dll loading).

Prolog

And this explains the problem with Shell Extensions in application virtualization (App-V isn’t the only one with this problem). Our goal is to isolate the application, and yet sometimes these Shell Extensions need access inside the virtual environment.

Oh, much of the time the shell extension is very simple and doesn’t need access to the virtual environment to perform it’s magic. You just provide the shell extension COM object and appropriate registration and the extension works.

But you really can’t tell when it won’t appear by looking at the registration or the COM dll file. You can only tell by testing. Of course, most of the time we don’t even know what to look for (vendors don’t document shell extensions).

I have learned enough to know how to make this shell extension work under App-V 5 by extending the integration process even further, but it just isn’t worth it. Unless the missing functionality is critical to the application use, the work to find everything that is needed and exposing more and more of the virtualized assets as part of the publishing processes just is not justified by the reward.

PostScript: A Call for Help to the Authorities

The right solution remains for Microsoft to figure out how to provide the explorer shell with access to all of the virtualized package assets, but only for the purpose of implementing the shell integrations. This might eliminate the need for all of the publishing actions.

Now where is that phone number? Is that missing too…

Better detection in 4.6SP2

You just gotta love how Microsoft sneaks things in.

4.6SP2 is pretty much a rollup of hotfixes (almost all of them since 4.6SP1 came out), plus support for Windows 8, Server 2012, and additional client changes for transitional dual client scenarios with App-V 5. As always, you should check the Readme documentation for details, but in the time honored tradition of making changes without telling us, there is more. And when someone in the community finds one, it is nice for them to tell everyone.

So here is one. The following screen shot is from the 4.6Sp1 sequencer:

And here is what the same screen looks like with the same app on 4.6.2:

So it looks like an improvement to the detection logic, or perhaps more accurately, a bugfix to faulty improvement logic. Maybe that means they also fixed the one where it sometimes misses device drivers?

It is nice that they fix these things, I just wish that they would acknowledge it so that we know not to trust the version currently in use by most companies!