Cutting Edge Silverlight4 COM+ Features

JustinAngel

Hi Folks,

The new Silverlight 4 COM+ Automation feature can be used to perform a myriad of previously unavailable tasks in Silverlight. In this blog post I’ll review some of these tasks, what COM+ Automation is, some related issues and helpful introduce developer tools.

What is Silverlight 4 COM+ Automation support?

Silverlight 4 Beta 1 offers the ability to initialize and use COM+ classes from Silverlight. It should be noted that these features are only available in elevated privileges Out-Of-Browser mode and are not available in-browser. In Silverlight 4 Beta1 Com+ Automation only works on Windows machines (but more on that later).

Nooo! COM+ killed my inner child back in the 90s!

Get over it.

Silverlight 4 COM+ Automation is not about authoring, deploying or versioning COM+ components, that is a worst practice for this feature. The best practice for Silverlight 4 COM+ is to only use common operating system COM+ classes, and not ship your own.

Given that best practice, you are just the consumer of some time tested Windows APIs. Using COM+ Windows APIs is no different then consuming the .Net framework, 3rd party frameworks or p/Invoke features.

Stop yapping and show me how to setup a Silverlight 4 OOB project!

We’ll start by creating a new Silverlight 4 OOB (Out Of Browser) project with Elevated Privileges in Visual Studio 2010.

For our test project we don’t need a Server-Side project, and we need to make sure we’re using Silverlight 4.

Right-Click on the SL4Com project and choose “Properties”. Check the “Enable Running Application out of browser”.

Click “Out of Browser Settings” and set “Require Elevated Trust when running outside the browser”.

Essentially, what this method does is: 1. Gets the path for all the users start menu links. 2. Gets the specific link for Calculator. 3. Checks what Verbs are available for that link. 4. Execute the “Pin to Taskbar” verb.

And when running this application we can see Calculator is now pinned to the user’s taskbar:

Feature #6: Read any Registry values

Using the Shell.Application RegRed method you can read values from the machine’s registry.

At the "HKLM\Software\Microsoft\Windows\CurrentVersion\CommonFilesDir" registry key we can see the location of the machine’s Common Files:

Feature #7: Add OOB App to Windows’ Startup

Using a combination of the LNK technique we’ve seen earlier and Shell.Application RegWrite method we can add our OOB app to the Windows’ startup applications. Every program listed under “HKLM\Software\Microsoft\Windows\CurrentVersion\Run\” will be executed when the machine first starts up. So if we can get our OOB link and add it to that Registry location, we can add our OOB application to Windows’ Startup.

MessageBox.Show("Please restart your machine and this application will load on startup.");

}

}

}

This code snippet isn’t all that complicated. First, we get the LNK to the current out-of-browser application by checking the start menu links directory. Next, we add that LNK file Uri to the registry node we mentioned earlier on.

And after running clicking the button we can see the registry value was added:

Task #8: Pinning the OOB Application to Windows’ 7 Taskbar

We’ve previously seen how to get the LNK for the OOB application and we’ve seen how to pin those LNKs to the Taskbar. It’s fairly easy to combine those two techniques to pin the current OOB app to the taskbar.

Note: this code snippet does not show best practices for using ODBC for Silverlight. For one thing, Commands should use parameters and not strings.

If you were to execute this code sample you’d probably get the following error:

Since you don’t have the Northwind Database installed or the username & password are wrong you’d see some exception or another. Allow me to assure you “It works on my machine”!

It is important to discuss best practices at this point. It is not my intent to advocate executing local SQL statements in conjunction with a local database.

However, It is possible to convert any 3rd party OR/M or Persistence layer to run on ODBC. Which would make for a very comfortable EF/Linq2SQl/NH like syntax. In that case, it would be much more acceptable to use ODBC.

Another issue with this method is the end-user might not have any local database available. And you’ll end up resorting using Access or the likes.

Personally I believe that for local Silverlight storage we should use local OODBs, and not use ODBC.

Feature #11: Automate Scanners and Cameras

Using the WIA (Windows Image Acquisition) infrastructure we can automate external Scanners, Cameras and Video cameras. Many very unique samples (converting file formats, getting scanners to scan, taking pictures, etc) are available at the WIA Samples page.

One possible task is to iterate over all Cameras and Scanners currently connected to the local machine and their commands:

The above code is actually pretty simple. 1. We initialize a DeviceManager. 2. We ask for all the DeviceInfos. 3. We then iterate over all devices, getting their commands. 4. We display the command name and device name.

On my dev machine with an External Scanner and External Camera, this is what we see:

When clicking the button on my local machine we’ll see the following dialogs:

And we can see c:\myImage.jpg is indeed that same photo:

Feature #13: Use the Windows 7 Location API

As part of Windows 7 the Location API was added to provide developers with the current machine GPS location. If the proper hardware is connect, Using the Location API we can get the current Latitude and Longitude of the current Machine.

The above code will display the current Latitude and longitude and then listen in for new reports every 5 seconds.

Feature #14: Use Classes from the Full .Net framework

While it is not recommended, you can consume some classes from the full .Net framework. The reason it is not recommended, is because all of your users would need to have the full .Net framework installed.

Here’s an example of initializing the ReaderWriterLock class used for multithreading multiple readers or a single writer.

<Button x:Name="btnUseFullDotNet" Content="Use a class from the full .Net frameowrk" Click="btnUseFullDotNet_Click"/>

This code might look complex, but it really isn’t. 1. We’ve initialized a WbemScripting.SWbemLocator and connected to the local Machine with proper security. 2. We’ve executed a WMI Query for all storage changes on C:\. 3. When that event fired we’ve shown a messagebox.

Since Wbem doesn’t directly support events, we have to constantly query it. So we’re executing the whole thing in a background thread.

Executing this code and adding c:\foo.txt file will cause the following messagebox to occur:

Feature #16: Iterate over valid ProgIDs

This one is just a shout-out to the COM infrastructure. If you’ve been paying attention you’ve noticed some magic strings when calling ComAutomationFactory.CreateObject.

Those magic strings are the ProgIDs of registered COM+ components. We can get a list of all valid ProgIDs using WMI.

@"SELECT Caption, Description, InprocServer32, ProgID FROM Win32_ClassicCOMClassSetting where progid is not null");

for (int i = 1; i < 25 /*QueryResults.Count*/; i++)

{

string progID = QueryResults.ItemIndex(i).ProgID;

sb.AppendLine(" " + progID);

}

}

MessageBox.Show(sb.ToString());

}

After clicking the button we can see this list of the first 25 valid Classes for Com+ Automation:

Feature #17: Automate Microsoft Office

Office exposes a set of COM+ automation classes allowing to automate PowerPoint, word, excel, outlook, etc. There’s been quite a lot written on this one so It’ll suffice to provide links to what’s already been said by folks more knowledgeable than myself:

Tools for Silverlight 4 COM+ Development

When developing Silverlight COM+ applications these 4 tools will prove to be invaluable source of information.

Tool #1: WMI Explorer

WMI Explorer is a general purpose tool used to visualize WMI queries. (Which we’ve seen earlier) Using WMI Explorer and the following query we can see a list of all available COM+ Components on the relevant machine:

SELECT Caption, Description, InprocServer32, ProgID FROM Win32_ClassicCOMClassSetting where progid is not null

This list is extremely helpful when examining which ProgIDs are available for COM Automation.

Tool #2: DLL Export Viewer

When working with dynamic types there’s no intellisense available. But fear not, using DLL Export Viewer we essentially get the same information reflector would have provided us on an assembly.

Tool #3: Resharper

Though development with dynamic types doesn’t offer intellisense, Resharper 5 makes this a little better by offering intellisense on members that have been previously used.

Notice the intellisense for the “Run” and “SendKeys” methods.

Tool #4: MSDN and Search Engines

Most core Windows’ COM+ components have adequate documentation up on MSDN when searching for the type name on google:

In case the documentation on MSDN is missing or just irrelevant (and that’s quite common) search “CreateObject <ProgID>” and the VBScript results are easily portable to C#.

But What about Macs?

COM+ Automation isn’t supported for Macs in Silverlight 4 Beta 1. For a good reason, Mac doesn’t have COM+.

However, Microsoft have stated they are looking into getting COM+ support working in Silverlight 4 RTM on a Mac.

Macs have similar programmatic access to COM known as AppleScript.

It’s not that hard to read once you remove the added spaces and add some indents. Once you get past the syntax, it’s easy to see those are the same classes and members on a Mac as are available for Windows.

The point here is that if Microsoft wants to enable Com Automation-like features on a Mac there are 2 options:

1) Enable executing AppleScripts.This option will let us have the same amount of control on a mac machine as we do on a windows machine.

2) Add an overload to ComAutomationFactory.CreateObject() that calls the “Tell Application” command under the scenes and gets a AppleScript object. This option would work extremely well for Office automation. For any other operating system feature, you’ll have to code OS access twice.

If Microsoft chooses to not go ahead with Mac support in Silverlight 4 RTM, well, it’s not because they couldn’t.

What about Linux?

Moonlight has had the superior security model since it first shipped. Mono supports hosting Moonlight in a GtkWidget that has full-trust capabilities. So while Silverlight has an elevated privileges model, Mono has a full trust model.

Can I author .Net components and then deploy them as COM+ components?

It is possible yet tremendously cumbersome. Consider that you’ve just added a requirement for the full desktop CLR when running in Silverlight. Some of your users might not have .Net (or the right .Net version) installed. Additionally, you’ll still back into COM+ DLL versioning hell.

If you’re going to take that level of dependency it might be best if you moved over to WPF.

Or, if you insist on taking a .Net dependency you shouldn’t use COM+ for communication. It’d be best to use WCF for that. Michael Wolf has a good blog post demoing how to create that connection.

Fin

In this blog post we’ve reviewed many new features enabled by Silverlight 4 COM+ support. We’ve also covered how to best use this new feature including tools, best practices and the possible future of this feature.

Leave A comment

I’d love to hear what you think of Silverlight 4 COM+ automation? Better yet, if there’s some novel use of Silverlight 4 COM+ I haven’t shown here, feel free to link to it.