Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Silverlight 4: Accessing Windows 7 Taskbar using the new COM API

0.00/5 (No votes)
17 Jun 2010 1  
Silverlight 4 has the power to talk with any other application using the COM API. 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.

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 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 articles [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 it in a step-by-step manner 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-to-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 at the below snapshot:

pic_01.png

The pinned applications which are not opened will look like a flat icon whereas the opened applications (whether they are 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.png

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 at the below figure:

pic_03.png

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 how you can access the taskbar. Read the full article and provide your feedback/suggestions.

Prerequisite

To develop this simple application, you need the following tools installed in your development environment:

  • Windows 7 Operating System (required 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.png

  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.png

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 CodeProject.

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.png

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.png

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 controls 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 have some 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.png

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 the 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 have 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 runs 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.png

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 prompts 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.png

pic_09.png

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_10.png

pic_11.png

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.

History

  • Initial post - 18th June, 2010

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 fulfill 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. 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 and don't forget to provide your feedback/suggestions. This will give me an opportunity to improve my articles.

Enjoy reading my articles @CodeProject and @MyBlog

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here