Silverlight 4: Interoperability with Windows 7 Taskbar using COM



Microsoft released Windows 7 last year which has lots of functionalities including a nice UI. Among those features one of the most user friendly feature is Pin/Unpin application to Taskbar. You can develop WPF or Windows Forms applications in which you can implement this feature. But do you know that this is also possible in Silverlight? Yes, Silverlight 4 has the power to talk with any other application using the COM API. You can read one of my earlier article [Silverlight 4: Interoperability with Excel using the COM Object].

pic_01 

In this Article I will show you how we can talk with the Windows 7 Taskbar. Read the complete Article and provide your feedbacks or suggestions.


Table of Contents



Introduction

Microsoft released Windows 7 last year which has lots of functionalities including a nice UI. Among those features one of the most user friendly feature is Pin/Unpin application to Taskbar. You can develop WPF or Windows Forms applications in which you can implement this feature. But do you know that this is also possible in Silverlight? Yes, Silverlight 4 has the power to talk with any other application using the COM API. You can read one of my earlier article [Silverlight 4: Interoperability with Excel using the COM Object].

So, how can I develop such functionality in my Silverlight 4 application? Here I will describe you step-by-step to let you know about the feature. After reading this article you will be able to pin/unpin any Windows application to your Windows 7 taskbar directly from your Silverlight 4 out-of-browser application.


Background

In Windows 7 operating system you can pin any application for easy access like the earlier quick launch toolbar in a new way. Once you right click on the taskbar icon you will get some quick tasks right to the context menu as you do for regular day-2-day activity. There is an option to Pin/Unpin the application in taskbar. Once pinned, you can open that application directly from the taskbar.

Have a look into the below snapshot:

pic_01 

The pinned applications which are not opened will look like a flat icon whereas the opened applications (whether it is pinned or not) will have a rectangular border with some glossy background as shown above.

When you right click on an unpinned application from the taskbar you will see a Menu having an option to pin that program to the taskbar like this:

pic_02

Once pinned to the taskbar if you again right click on the icon you will see that the “Pin this program to taskbar” menu item has been changed to “Unpin this program from taskbar”. Have a look into the below figure:

pic_03

Silverlight 4 has a great feature like accessing the Taskbar using the COM API. In my earlier article I demonstrated another feature called “Accessing Microsoft Excel Application using Silverlight 4 COM API”. In this article I will demonstrate you how you can access the taskbar. Read the full article and provide your feedbacks/suggestions.

Prerequisite

To develop this simple application, you need the following tools installed in your development environment:
• Windows 7 Operating System (must to run the application)
• Visual Studio 2010
• Silverlight 4 Tools for Visual Studio 2010

Remember that, Silverlight 4 applications can be developed only in Visual Studio 2010. Hence, if you have Visual Studio 2008 installed in your PC, you can install Visual Studio 2010 side-by-side for exploring Silverlight 4.

Getting Started

If your development environment is ready, then we can proceed towards creating a new Silverlight Application project. At the end of this part, we will be able to run our first Silverlight application inside the browser.

1. Open your Visual Studio 2010 IDE
2. Select File > New Project or just press CTRL + SHIFT + N to open up the New Project dialog
3. Expand the “Visual C#” node and then go to sub node “Silverlight”
4. Select “Silverlight Application” in the right pane
5. Select proper location to store your application (let’s say, “D:\Sample Apps\”
6. Now enter a proper name for your project (call it as: “Silverlight4.Interoperability.Taskbar”)
7. Select the .NET Framework version from the combo box at the top (I am using .NET Framework 4.0)
8. Click OK to continue
9. In the next dialog, make sure that “Host the Silverlight application in a new Web site” option is selected
10. Choose “Silverlight 4” as the Silverlight Version and hit OK

Wait for a while, Visual Studio will now create the Silverlight solution for you to use which will contain a Silverlight Project and one Web Application Project to host your Silverlight application. In your Silverlight project, you will find a “MainPage.xaml” & an “App.xaml” file which are already created for you by the IDE Template.

Once you are done with setting up the project, you need to add an Assembly Reference to the Silverlight project. We will use the “dynamic” keyword and for this we need to add the “Microsoft.CSharp” assembly reference.

1. Right click on the “Reference” folder inside the Silverlight project and click on the “Add Reference” menu item from the context menu.

pic_04 

2. This will open up the “Add Reference” dialog on the screen. Scroll the window to find the assembly named “Microsoft.CSharp” from the .NET tab. Select it and click “OK”. This will add the Microsoft.CSharp assembly reference into your Silverlight project. Once added your project will support dynamic variable declaration.

pic_05

Configuring Out-Of-Browser Settings

Once you are done with setting up your Silverlight project, we are ready to implement custom Out-of-Browser Window for our application. You can read the complete article on Creating Silverlight 4 Custom Out-of-Browser window from http://www.kunal-chowdhury.com/2010/03/silverlight-4-how-can-i-create.html.

Once you design your out-of-browser Window, go to the properties of the Silverlight project. From the Silverlight pane, be sure that you are using “Silverlight 4” as target version. Now select the “Enable running application out of browser” which will make the “Out-of-Browser Settings…” button enabled. Click on it for more settings.

pic_06

From the Settings dialog window, select “Show install menu” which will create a Menu Item inside the Silverlight context menu. Once you run your application and right click on the application, you will see an “Install” menu item on it. I will come to this section later.

pic_07

Now, check the “Require elevated trust when running outside the browser” as shown above and choose “Window Style” as “No Border”. Once you are done with these settings, click ok to save the configurations. You can also change the “Window Title”, “Size” and other options available there.

Designing the XAML Page

Let us start designing the XAML page for showcasing our example. In our demo example, we will add three TextBox control along with three Buttons. When the application starts, it will populate the location of the files (e.g. Wordpad, Paint and Calculator) which we want to Pin/Unpin into the Windows 7 Taskbar inside the TextBoxes. There will be a button near to each Textbox. Once clicked on the button it will Pin the application in the Taskbar (provided the application is not already pinned). If the application is already pinned to the taskbar, it will Unpin from there.

Below is the complete XAML code of my example:
<UserControl x:Class="Silverlight4.Interoperability.Taskbar.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Border BorderBrush="Black"
Height="177"
Width="600">
<Grid x:Name="LayoutRoot"
Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="31" />
<RowDefinition />
</Grid.RowDefinitions>

<Border BorderBrush="Black"
CornerRadius="10,10,0,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Black" />
<GradientStop Color="Black"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
</Border>
<Border BorderBrush="Black"
CornerRadius="10,10,0,0"
MouseLeftButtonDown="Border_MouseLeftButtonDown"
Margin="2,2,2,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="White" />
<GradientStop Color="Transparent"
Offset="0.69" />
</LinearGradientBrush>
</Border.Background>
<Border x:Name="brdClose"
BorderBrush="#FFE9D710"
BorderThickness="1"
HorizontalAlignment="Right"
MouseLeftButtonDown="brdClose_MouseLeftButtonDown"
Margin="0,5,8,6"
Width="22"
Height="18"
Background="#FF700C0C">
<TextBlock TextWrapping="Wrap"
Text="X"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="13.333"
Foreground="White"
IsHitTestVisible="False" />
</Border>
</Border>
<Border BorderBrush="Black"
BorderThickness="1"
Grid.Row="1" />
<TextBlock HorizontalAlignment="Left"
Margin="9,7,0,8"
TextWrapping="Wrap"
Text="Windows 7 Taskbar Demo"
IsHitTestVisible="False"
d:LayoutOverrides="Height"
FontWeight="Bold"
FontSize="13.333"
Foreground="White" />
<TextBox x:Name="txtWordpad"
Height="22"
Margin="8,8,91,0"
Grid.Row="1"
TextWrapping="Wrap"
VerticalAlignment="Top"
IsReadOnly="True"
Background="White" />
<Button x:Name="btnWordpad"
Content="Pin/Unpin"
Height="25"
Click="btnWordpad_Click"
Grid.Row="1"
Width="80"
Margin="0,6,6,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
d:LayoutOverrides="Width, Height"
Foreground="White" />
<TextBox x:Name="txtPaint"
Height="22"
Margin="8,36,91,0"
Grid.Row="1"
TextWrapping="Wrap"
VerticalAlignment="Top"
IsReadOnly="True"
Background="White" />
<Button x:Name="btnPaint"
Content="Pin/Unpin"
Height="25"
Click="btnPaint_Click"
Grid.Row="1"
Width="80"
Margin="0,34,6,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
d:LayoutOverrides="Width, Height"
Foreground="White" />
<TextBox x:Name="txtCalculator"
Margin="8,66,91,58"
Grid.Row="1"
TextWrapping="Wrap"
IsReadOnly="True"
Background="White" />
<Button x:Name="btnCalculator"
Content="Pin/Unpin"
Height="25"
Click="btnCalculator_Click"
Grid.Row="1"
Width="80"
Margin="0,64,6,57"
HorizontalAlignment="Right"
Foreground="White"
d:LayoutOverrides="Width" />
<TextBlock x:Name="txbMessage"
Margin="8,0,8,22"
Grid.Row="1"
TextWrapping="Wrap"
FontWeight="Bold"
Foreground="Red"
VerticalAlignment="Bottom"
TextAlignment="Center"
FontSize="12" />
</Grid>
</Border>
</UserControl>

Playing with the Code

Let us do a fun writing the code. First of all, we will populate our TextBoxes with the location of three different applications (Wordpad, Paint and Calculator). Remember that, there are some restrictions in Silverlight while accessing local files. Hence we will use some trusted location for our case.

The method GetFolderPath() will return the Start Menu -> All Programs -> Accessories directory which we will set as the value of the TextBox after appending the Filename. Before setting the path let us discuss about the lines inside the method.

1. As a first step, we need to create the Shell Application object from the AutomationFactory.
2. Once we have the Shell Application instance we can get the common programs folder. We can get it by passing the value "23" to the NameSpace method. 23 is the namespace of the Windows Common Programs directory path. We will store it in a local dynamic variable named "commonPrograms" for later use.
3. commonPrograms.Self.Path will return the exact path of the Common Programs folder.
4. We will append "Accessories" with this path so that we can get the exact location from where we have to pickup the Application files.

private string GetFolderPath()
{
using (dynamic shellApplication = AutomationFactory.CreateObject("Shell.Application"))
{
// get the common programs folder using the namespace
dynamic commonPrograms = shellApplication.NameSpace(23);

// commonPrograms.Self.Path will return => 
// "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs"
string folderPath = string.Format("{0}\\{1}",
commonPrograms.Self.Path, "Accessories");

return folderPath;
}
}

On page load we will call this method and populate the TextBox field with the exact location. Here is the code for it:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
txtWordpad.Text = string.Format(@"{0}\{1}.lnk", GetFolderPath(), "Wordpad");
txtPaint.Text = string.Format(@"{0}\{1}.lnk", GetFolderPath(), "Paint");
txtCalculator.Text = string.Format(@"{0}\{1}.lnk", GetFolderPath(), "Calculator");
}

If you run the application now, it will look as below:

pic_12

Let us now go more into depth to implement a method which will take the filename as a parameter and check if the program is already pinned to the taskbar or not. If it is not pinned, the code will pin the application and if it is already pinned, it will unpin that. Let's write the code:

private void PinToTaskbar(string fileName)
{
// create the shell application object
using (dynamic shellApplication = AutomationFactory.CreateObject("Shell.Application"))
{
// get the accessories directory
dynamic directory = shellApplication.NameSpace(GetFolderPath());

// get the full application path
dynamic link = directory.ParseName(fileName + ".lnk");

dynamic verbs = link.Verbs();
for (int i = 0; i < verbs.Count(); i++)
{
dynamic verb = verbs.Item(i);
string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();

if (verbName.Equals("pin to taskbar"))
{
verb.DoIt();
ShowMessage(fileName + " has been pinned to your taskbar.");
}
else if (verbName.Equals("unpin from taskbar"))
{
verb.DoIt();
ShowMessage(fileName + " has been unpinned from your taskbar.");
}
}
}
}

The first line is same as described earlier. Once we have the Shell Application instance we will get the Accessories directory from the shell namespace by calling the GetFolderPath(). Now append the filename with the extension to the whole path. We have to use .lnk as extension here because we are accessing it from the Start Menu folder where all the applications has a shortcut link which is nothing but an extension of .lnk.

Once we have the full application path, we can retrieve the context menu items assigned to the application by calling Verbs(). Now, we will iterate through each item and retrieve the item name:

dynamic verb = verbs.Item(i);
string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();

Now we will check if the item name is "pin to taskbar", means the application is not yet pinned to your taskbar. So pin it to taskbar by calling verb.DoIt(). If the item name is "unpin from taskbar", means it is already pinned to the taskbar. Hence, we can unpin it by calling the verb.DoIt() again. The call to verb.DoIt() actually executes the shell to run the selected item command.

On the button click implementation we have to just call this method by passing the application name i.e. "Wordpad", "Paint", "Calculator" etc. and once clicked it will check the name and do what we exactly told it to do.

Playing with the Application

It was a big time writing the code & designing the UI for our application. Now let us run the application and see what we have implemented till now.

Once it run your application (if it opened in Browser mode, please install it as Silverlight Out-of-Browser application and run from your desktop) you will see the following Window:

pic_12

Click the "Pin/Unpin" button near to the TextBox for "Wordpad" application. You will see that the Wordpad icon has been added to your Windows 7 Taskbar (provided that the icon is not already pinned) and it prompt a message "Wordpad has been pinned to your taskbar." Let us do the same for the other buttons also. You will see that the applications are pinning to the taskbar when you clicked on the respective button.

pic_08 

pic_09

Let us click the buttons again one by one. You will notice that the applications are unpinned one by one from the taskbar as and when you are clicking the respective button and prompts a message "<APP_NAME> has been unpinned from your taskbar."

pic_11

pic_10 

Wao, what a nice feature!!! Yeah, that's great. We can access the Windows 7 taskbar directly from the Silverlight application (OOB only). Earlier only Windows standalone applications had the rights to access it. Now it's the time of Silverlight too.

End Note

I think, from this article you got the initial idea on the Silverlight COM API to access the Windows 7 Taskbar. Now you can think about your business application to do something new in Silverlight. Many more functionalities are there. Not only this, you can even access the Windows Registry too. So, explore more using the COM API to fulfil your business need.

If you are interested, you can download the sample source code written for this Article. Not only this, you can even download the demo zip also. Just run the file named "install". It will install the Silverlight XAP application automatically and create the Shortcut to the application in your Desktop and Startmenu. Open the file to execute the sample application.


Please Vote for this Article @CodeProject and Don't forget to provide your Feedbacks/Suggestions. This will give me opportunity to improve my Article.

Enjoy reading my Articles @CodeProject and @MyBlog.

3 comments

  1. Dude,
    How do you pin the current running OOB application to the taskbar this will be an useful scenario.

    ReplyDelete
  2. you will also want to look at the following

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

    this allows for native style integration for oob apps.

    ReplyDelete
  3. I really like the snapshot images in this post. The way they display like the reflections in water, made me look into this post once more.
    http://www.windows7port.com/641/windows-8-system-requirements-and-consumer-preview-download-links/

    ReplyDelete


 
© 2008-2014 Kunal-Chowdhury.com | Designed by Kunal Chowdhury
Back to top