In short: I discuss Sidebar Gadgets, and I show you how to invoke a CardSpace-protected WCF service from a simple Gadget. Full source code is provided, along with detailed commentary on the road I've followed for getting there. Added bonus: the code shows how to apply an arbitrary configuration file to WCF, an issue often encountered when hosting WCF code in processes you don't control.
Sidebar Gadgets are mini applications which live in the Sidebar, a UI element on the Windows Vista desktop. They are extremely handy for keeping an eye on information you are often interested to; they are also very good at providing you a quick-reach UI for tasks you perform often. As you know I wear the server guy hat, so I'm not really the best person for explaining the advanteges of Gadget: I would suggest visiting Michael and Jaime blogs if you want more details on the subject.When I thought of how the gadget model could be useful for me, I realized that much of the information I'd like to keep an eye on happens to be confidential (like being notified if I received a wire transfer, or getting the access statistics from my website); the actions I want to take when I react to changes in those data are also requiring high security levels (like accessing a portion of my home banking for giving approval for a certain utility bill to be paid). So, would not be great if we could use CardSpace for authenticating the services accessed by a Gadget? I thought for few nights about the issue, devised a strategy and wrote a proof of concept. Yesterday night I finally got it working: below I walk you through the process. In attachment you'll find the source code: it's not very polished, so I am not posting it to the community website just yet.
Sidebar Gadget: a glance to the architecture
I am going to cover a minimal portion of the architecture, to the purpose of understanding how to plug CardSpace in it. Gadgets are so much more that the few things I throw down here, please take the time to take alook at the whole story. That said, let's dive into it.A sidebar gadget is, in extreme synthesis, an HTML file (Gadget.htm, for example) that will be rendered inside the Windows Vista Sidebar. As such, it can do pretty much everything that DHTML offers you PLUS it takes advantage of some APIs which handle some resource on the local system (some document folder like the pictures, storing and retrieving gadget-specific settings, etc). The gadget application is described by a manifest file, Gadget.xml, which enumerates various metadata such as application name, version, author info, location of the source file, location of images used as icons, platform requirements, permissions required... a classical manifest.A gadget can also have other HTML files that are shown on specific moments: it is possible to provide a custom UI for changing the gadget settings (typically settings.htm), and a custom UI that pops up from the gadget (typically flyout.htm) and gives more real estate outside of the boundaries of the sidebar. In our walkthrough we don't use those two further UIs, but in a real gadget application you will likely leverage them. All the .HTM files in a gadget can make use of the classical web UI entourage, such as *.JS and *.CSS files; and images, naturally. All those files (and subfolders, if any) should live in the same folder as Gadget.htm and gadget.xml.Deploying a gadget is super easy: you zip the folder containing the above, you change the .ZIP extension to .GADGET and you obtain a file that can be easily installed. Now, there's a rougher way of deploying a gadget. You take the same folder above, but instead of zipping it you just copy it under %userprofile%\AppData\Local\Microsoft\Windows Sidebar\Gadgets. Then you just click on the plus sign on top of the sidebar (what? You're not running it already? Just type sidebar in the search field in the start menu, the shortcut to it is usually the first result) and pick your gadget for having it instantiated (you can have multiple copies).How does the typical gadget work? Like a web page from where you cannot leave. All UI updates are made using AJAXy tricks, refreshing only the parts of the UI that need updating. Sometime you can also "cheat" and embed in the page an ActiveX (any flavour you want), or an XBAP. It's that easy.
Injecting CardSpace in a gadget
Grocery list style:
Now that we got a good feeling of how it should work, let's walk through the code of the various parts of the solution.
The sample gadget
I am going to describe you a very, very simple gadget: it will turn out pretty ugly from the visual standpoint, but I'm OK with it. The extra code required for the prettification would ruin the signal/noise ratio, and I want to make my best for making you understand the fine points about cardspace and WCF here. You can add cosmetics later :-)Our gadget will display a list of roads: by pressing a button, we will get traffic info from a web service and we will change the color of every road name according to the traffic levels (green=good, red=bad, etc). The service that returns the traffic info will be secured via Windows CardSpace. If you're a loyal reader, that may sound familiar to you: this is exactly one of the services featured in my WPF sample. In fact, in the spirit of frugality of this post, the gadget we are creating here will call exactly that service. This means that for testing the gadget you'll need to download the sample from here (detailed blog post here) and you'll need to have TrafficService running when you use the gadget (if you don't, you'll still see cardspace popping up: but afer you select a card the call will fail). You will not need anything else from the WPF sample: also, I won't use any of the token caching technology I introduced at the time even if it actually makes sense.Now that we know what the gadget is supposed to do and what we need on our "backend", let's finally dive into the details of the implementation.
Let's start with the basic Gadget-ry. What do we need to deploy in %userprofile%\AppData\Local\Microsoft\Windows Sidebar\Gadgets? The following:
The manifest file is very, very simple:
<?xml version="1.0" encoding="utf-8" ?>
<info url="http://blogs.msdn.com/vbertocci" text="More Gadget Info"/>
<copyright>© 2007 by theGadgetOwner</copyright>
<description>A proof of concept: invoking a CardSpace-protected WCF method from a sidebar gadget</description>
<icon height="100" width="125" src="images/gadgetIcon.png"/>
<base type="HTML" apiVersion="1.0.0" src="gadget.htm"/>
The only part that really interests us is the one highlighted in yellow, where we specify that the source file is "gadget.htm" and that we need permissions Full. For details on the gadget manifest format, please refer to the gadget development documentation. Also note: all the .PNG files referred in the manifests are what constitutes the content of the folder images.
The file Gadget.htm is much more interesting:
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
var myControl = new
var myList = myControl.GetTrafficConditions();
var colorArray = myList.split(",");
document.getElementById("Road1").style.backgroundColor = colorArray;
document.getElementById("Road7").style.backgroundColor = colorArray;
<input type="button" onclick="GetTraffic()" value="Get Traffic Info" />
<div id="Road1">Road 1</div>
<div id="Road7">Road 7</div>
All the parts not highlighted, like the CSS definitions, are of no interest for us in this context and will be ignored.Starting from the body:
Let's take a close look at the definiton of the GetTraffic function.
The text highlighted in yellow indicated code that deal with the ActiveX.The first line instantiate the ActiveX by its ProgID, WCFCardSpaceActiveX.WCFCardSpaceActiveXClass. No indication that this is a .NET assembly.The next two lines feed the ActiveX instance with the path of the WCF configuration file and the path of the assembly on your file system. Chances are that you will have to simply substitute "myaccount" with your user alias.The fourth line invokes the main method of the ActiveX, GetTrafficConditions(), and saves the return value on a local variable.
The green code is just UI update; we go thorugh the list and we change the color of the DIVs accordingly.
That's it! From the Gadget developer perspective, it's so easy it's not even funny. If we take a look to the activex code, though, we'll find that the music changes.
Below you can see the project structure for the custom activex assembly:
The output of the project is a class library, that should be copied in the same folder as gadget.htm, gadget.xml and so on.THe resulting assembly must be registered as COM object. If you are using visual studio, you can avoid using regasm for registering the assembly under COM. If you go on project properties->build tab, you will find a "Register for COM interop" checkbox; check it, and next time you'll build the project the assembly will be registered. If you want to do everything by hand, you can use regasm from the command line.As you will read in the <Digression/> block below, for this example you have also to install the assembly in the GAC. THat's easily done via the command line tool gacutil. I am looking at eliminating the GAC requirement. Let's take a look at some notable file in the solution.
The TrafficServiceContract.cs file it taken verbatim from the WPF sample mentioned above, the one containing the WCF service our gadget will invoke. It just contains the contracts definition for the service we want to invoke. I won't paste it here.
The App.Config is identical to WCFCardSpaceActiveX.dll.config. It is substantially a simplified version of the WPF client config in the WPF sample mentioned above: I have just got rid of all the config for the other service (MeteoService), not used here, and I eliminated all the token caching configuration. Even if it's not very interesting nor new, I will paste it here in case you want to take a look.
If your service listens on a different port, or if it is remote, the highlighted value must be changed accordingly.
We finally got to the real meat of the post, the code behind WCFCardSpaceActivexClass. Since it is longer than the others and somewhat denser, I am going to break down the file in more sections. Let's start with the main ActiveX class declaration:
// Our ActiveX class
public partial class WCFCardSpaceActiveXClass : UserControl
public void SetApplicationBase(string applicationBase)
_applicationBase = applicationBase;
public void SetConfigurationFile(string configurationFile)
_configurationFile = configurationFile;
The yellow code shows the attributes needed for exposing the class as ActiveX. We have seen that ProgId used from the Gadget.htm code for instantiating this class.The AutoDual interface is useful for being able to use the current class via scripting.The green and light blue code handle the acquisition of the applicationbase and configuration file paths, respectively. Again, we have seen those methods invoked from Gadget.htm.
The method that Gadget.htm invoked for getting the results was GetTrafficConditions: here there's how it is implemented.
public string GetTrafficConditions()
string temp = "";
//get our assembly among all the ones in the current AppDomain
Assembly  alist = AppDomain.CurrentDomain.GetAssemblies();
string myAssemblyName = String.Empty;
foreach(Assembly a in alist)
myAssemblyName = a.FullName;
//set up the AppDomain for the WCF proxy wrapper class TrafficServiceCaller
AppDomainSetup ads = new AppDomainSetup();
ads.ApplicationBase = _applicationBase;
ads.DisallowBindingRedirects = false;
ads.DisallowCodeDownload = true;
ads.ConfigurationFile = _configurationFile;
// Create the AppDomain for the WCF proxy wrapper class TrafficServiceCaller
AppDomain ad2 = AppDomain.CreateDomain("AD #2", null, ads);
// Instantiates the TrafficServiceCaller wrapper class in the new Create an instance of MarshalbyRefType in the second AppDomain.
// Gives back a transparent proxy to our TrafficServiceCaller instance, so that we can call it from the main AppDomain
TrafficServiceCaller mbrt = (TrafficServiceCaller)ad2.CreateInstanceAndUnwrap(myAssemblyName,
// Calls the method of the wrapper that will invoke the web service (& summon the CardSpace UI)
temp += mbrt.GetTrafficConditions();
// Unloads the second AppDomain and destroys its content
This is the place where we perform the AppDomain trick. The light blue code retrieves the full name of the current assembly, as loaded in the sidebar root AppDomain: we will need it later, since the class that performs the actual WCF call lives here. I could have hardcoded the assembly full name, but that would not have been funny (and it would break easily every time you change something).The code highlighted in yellow creates a new AppDomain, assigning to it the config file we specified and forcinf the execution path to the folder where our assembly lives.The first line of green code creates an instance of our WCF caller class,TrafficServiceCaller, in the new AppDomain. This ensures that the WCF code in it will see the configuration file we specified, as opposed to the sidebar configurations settings. <Digression>This line was especially nasty to deal with, because I kept getting an error "cannot cast to transparent proxy". If I hosted the assembly from a console test application, however, everything worked. I know there are some subtleties about assembly resolution that can be fixed by overriding some system function, but I wanted a quick solution. Hence, I just installed my assembly in the GAC and everything magically worked. This is not ideal, since GAC instalaltion requires admin privileges: however we have to make some installation script or MSI anyway, since we need to register an ActiveX; furthermore if the gadget is used for high value transaction it probably makes sense to give the user a feeling that what they're installing is important stuff. That's what MIchael told me today, and I faithfully report it :) </Digression>Once we obtained the instance, we can call the method that will actually invoke the WCF service. After that, it's just cleaning.
The last thing we need to examine is the TrafficServiceCaller class, where we will finally see some WCF code.
public class TrafficServiceCaller: MarshalByRefObject
public string GetTrafficConditions()
ChannelFactory<TrafficService.ITraffic> cnFactory = new ChannelFactory<TrafficService.ITraffic>("TrafficClient");
TrafficService.ITraffic chn = cnFactory.CreateChannel();
List<TrafficInfo> ti = chn.GetTrafficInfo();
string temp = MapColor(ti.color);
for (int i = 1; i < ti.Count;i++)
temp += "," + MapColor(ti[i].color);
catch (Exception ee)
return ("Something went wrong: \n\n" + ee.ToString());
private string MapColor(int i)
case 0: return ("green");
case 1: return ("yellow");
default: return ("red");
That's it. We have seen how we can call a WCF service from one sidebar gadget, and use CardSpace for protecting the operation. The procedure is not necessarily straighforward, but it is not that hard and especially it does not require any hack.If you are not afraid of some handwork, you can try the above by playing with the code I am attaching to this post. Remember, this is pretty rough and requires some work from your side (downloading the CardSpace+WCF+WPF sample and launch the TrafficService, copying under your %userprofile%\AppData\Local\Microsoft\Windows Sidebar\Gadgets the folder CardSpaceWCFGadgetPoC.Gadget that you will find in the attached ZIP, launching regasm /codebase and gacutil -i on the WCFCardSpaceActiveX.dll file, adding the gadget from the gallery via the "+" button on the sidebar) but it's really not hard, and it actually helps to understand how the various moving parts interact. As usual, if eneough people asks for it I will package it in a full fledged sample. Have fun!
Last night the guys from Mindscape unleashed their powershell gadget onto the world. This very cool gadget
Really cool article. If I may, I'd suggest using Jonathan's ks code for .NET assembliesCOM assemblies:
(search for the entry using activex dlls in gadgets)
In this post I am going to show you an example of CardSpace and an Office application working together.
In this post I am going to show you an example of CardSpace and an Office application working together