Thursday, September 18, 2008

VistaBridge Considered Harmful; An Alternative

I've been playing with VistaBridge for a little while now, and the more I work with it, the more I realize that it's not ready for prime time. If you really look at the source, you'll see that it's filled with to-do's and comments along the lines of "This doesn't work". It tries to detect the presence of the correct version of comctl32.dll using an absolute path. The Visual Studio designer doesn't like some of its components: it won't display a window that uses task dialog progress bars and of the other VistaBridge controls.

Of course, VistaBridge is sample code; it was never intended to be used as-is in production code. Nevertheless, from web chatter it would appear that many developers have tried to use it. Developers should understand that it is unfinished--and apparently abandoned--code, so use it as inspiration only. [Update: not abandoned! See Kate Gregory's comment.]

The other problem with VistaBridge is that it just doesn't work very well.

There are a number of issues, but the biggest problem has been the dreaded "entry point not found" error when trying to call TaskDialog, TaskDialogIndirect, and the other Vista-only APIs. It was well understood that this probem had to do with side by side assemblies: these functions are present only in comctl32.dll version 6, but, for compatibility reasons, Vista will load an earlier version unless you tell it otherwise. The approach most people (including me) have been taking is to use a manifest. This has proven to be tricky, and may not be the right solution anyway, especially if what you're writing is a library: you don't necessarily want to force the entire application to use common controls 6.

The right solution is to push a new activation context when calling one of the Vista-only APIs. The activation context will use the correct version of comctl32.dll while leaving the rest of the application alone, and no manifest is required.

Fortunately, this is easy to do. Some very helpful people at Microsoft (thanks, Scott, Rob, and Anson) pointed me to some complete code that already exists in the MS Knowledgebase. The code from the article (KB 830033) does the trick as is. Even though the article is talking about a different issue (applying theming to Office add-ins), it does exactly what we want, and you can plop it into your application or library exactly as shown.

I've put together a C# class library that supports task dialogs using this technique and posted the Visual Studio 2008 solution here. The solution includes a simple demo app that displays a number of different styles of task dialogs, most of which are defined in XAML window resources. The library has not been through much testing, so use it to learn the techniques only. It's not intended for use in production code.

6 comments:

Anonymous said...

Hello,

I just wanted to say THANKS !!!

Have been struggling for days tryin' to get TaskDialog work under my VB WPF Project ...

You have done an outstanding job !

Anonymous said...

Good information. Quick note of caution about the activation context, however. That particular block of code in the MS KB article was essentially the code used by WinForms to obviate the need for a manifest to get themed controls (hence the var names). There's a gotcha with this approach though - the CLR only allows one version of a particular DLL to be loaded at any given time (well, in a given App Domain, but for 99% of apps, that means per process), so the first call to a DllImported function in comctl32 forces the CLR to load whatever version the OS loader thinks is the correct version. If the activiation context is active, you get what you want. If "somebody" - maybe WinForms, for instance - gets to comctl32 first and loads 5.82 instead of 6+ comctl32, then you're sunk.

Another interesting note about manifests: the OS caches whether the manifest exists or not when an app is first run. If no manifest is found, the loader doesn't look again until the executable is itself touched. So if you find the app misbehaves, you find out you need a manifest, you create one, then run again, you won't necessarily see the problem go away, until you rebuild for some reason, etc. This behavior might have changed since the last SP, but it was definitely there for awhile. The perf gains are considerable - but so is the frustration if you're wrestling with the manifest demons. :)

Anonymous said...

VistaBridge hasn't been abandoned at all. It started out as a sample buried down in the SDK samples tree and released as infrequently as the SDK. These days it lives on Code Gallery and its second release there was just days ago. http://code.msdn.microsoft.com/VistaBridge will get you the latest edition with some new samples. Please feel free to use the Issues and Discussions areas there to let the team know what you would like to see next.

Anonymous said...

Thanks a lot!

Anonymous said...

Try the new and improved bridge library:

http://code.msdn.microsoft.com/WindowsAPICodePack

Lot of new Win7 features, as well as the VistaBridge features.

nalanlagattuta said...

3D Iron Sticks for Tits of the Tits of the Tits of the Tits of the Tits of the Tits of the Tits of the Tits of the
A gold mine is constructed around the Tits of the Tits titanium tent stove of the Tits of the Tits of the Tits of the Tits of the Tits of the titanium trimmer as seen on tv Tits of the Tits titanium mens rings of the Tits of raft titanium the titanium plate flat iron Tits of the