Silverlight 4:使用新的 COM API 访问 Windows 7 任务栏






4.91/5 (25投票s)
Silverlight 4 能够通过 COM API 与任何其他应用程序进行通信。阅读本文后,您将能够直接从 Silverlight 4 浏览器外应用程序将任何 Windows 应用程序固定/取消固定到 Windows 7 任务栏。
目录
引言
微软去年发布了 Windows 7,它具有许多功能,包括漂亮的 UI。在这些功能中,最用户友好的功能之一是将应用程序固定/取消固定到任务栏。您可以开发 WPF 或 Windows Forms 应用程序,并在其中实现此功能。但您知道 Silverlight 也可以做到这一点吗?是的,Silverlight 4 能够通过 COM API 与任何其他应用程序进行通信。您可以阅读我之前的一篇文章 [Silverlight 4:使用 COM 对象与 Excel 进行互操作]。
那么,我如何在我的 Silverlight 4 应用程序中开发这样的功能呢?在这里,我将一步一步地进行描述,以便您了解该功能。阅读本文后,您将能够直接从 Silverlight 4 浏览器外应用程序将任何 Windows 应用程序固定/取消固定到 Windows 7 任务栏。
背景
在 Windows 7 操作系统中,您可以固定任何应用程序以方便访问,就像以前的快速启动工具栏一样。一旦您右键单击任务栏图标,您就会在上下文菜单中看到一些快速任务,就像您日常活动一样。有一个选项可以将应用程序固定/取消固定到任务栏。固定后,您可以直接从任务栏打开该应用程序。请看下面的截图

已固定但未打开的应用程序将显示为扁平图标,而已打开的应用程序(无论是否已固定)将具有矩形边框和一些闪亮背景,如下图所示
当您右键单击任务栏上未固定的应用程序时,您会看到一个菜单,其中有一个选项可以将该程序固定到任务栏,如下所示

一旦固定到任务栏,如果您再次右键单击图标,您会发现“将此程序固定到任务栏”菜单项已更改为“将此程序从任务栏取消固定”。请看下图

Silverlight 4 具有通过 COM API 访问任务栏的出色功能。在我之前的文章中,我演示了另一项功能,称为“使用 Silverlight 4 COM API 访问 Microsoft Excel 应用程序”。在本文中,我将演示如何访问任务栏。请阅读全文并提供您的反馈/建议。
先决条件
要开发这个简单的应用程序,您需要在开发环境中安装以下工具
- Windows 7 操作系统(运行应用程序所需)
- Visual Studio 2010
- 适用于 Visual Studio 2010 的 Silverlight 4 工具
请记住,Silverlight 4 应用程序只能在 Visual Studio 2010 中开发。因此,如果您在 PC 上安装了 Visual Studio 2008,可以并排安装 Visual Studio 2010 来探索 Silverlight 4。
入门
如果您的开发环境已准备就绪,那么我们可以继续创建一个新的 Silverlight 应用程序项目。在本文档的最后,我们将能够在浏览器内运行我们的第一个 Silverlight 应用程序。
- 打开您的 Visual Studio 2010 IDE
- 选择“文件”>“新建项目”或直接按 CTRL + SHIFT + N 打开“新建项目”对话框
- 展开“Visual C#”节点,然后转到子节点“Silverlight”
- 在右侧窗格中选择“Silverlight 应用程序”
- 选择合适的目录来存储您的应用程序(例如,“D:\Sample Apps\”)
- 现在为您的项目输入一个合适的名称(称之为:“
Silverlight4.Interoperability.Taskbar
”) - 从顶部的组合框中选择 .NET Framework 版本(我使用的是 .NET Framework 4.0)
- 单击“确定”继续
- 在下一个对话框中,确保选择了“在新的网站中承载 Silverlight 应用程序”选项
- 选择“Silverlight 4”作为 Silverlight 版本,然后点击“确定”
稍等片刻,Visual Studio 将为您创建一个 Silverlight 解决方案,其中包含一个 Silverlight 项目和一个用于承载 Silverlight 应用程序的 Web 应用程序项目。在您的 Silverlight 项目中,您会找到 IDE 模板已为您创建的“MainPage.xaml”和“App.xaml”文件。
完成项目设置后,您需要向 Silverlight 项目添加程序集引用。我们将使用“dynamic
”关键字,为此我们需要添加“Microsoft.CSharp
”程序集引用。
- 右键单击 Silverlight 项目中的“Reference”文件夹,然后从上下文菜单中选择“Add Reference”菜单项。
- 这将打开屏幕上的“Add Reference”对话框。滚动窗口在 .NET 选项卡中查找名为“
Microsoft.CSharp
”的程序集。选中它,然后单击“OK”。这将把Microsoft.CSharp
程序集引用添加到您的 Silverlight 项目中。添加后,您的项目将支持动态变量声明。
配置浏览器外设置
完成 Silverlight 项目设置后,我们就可以为应用程序实现自定义的浏览器外窗口了。您可以从 CodeProject 阅读有关创建 Silverlight 4 自定义浏览器外窗口的完整文章。
设计完浏览器外窗口后,转到 Silverlight 项目的属性。在 Silverlight 窗格中,确保您使用的是“Silverlight 4”作为目标版本。然后选择“Enable running application out of browser”(启用浏览器外运行应用程序),这将使“Out-of-Browser Settings…”(浏览器外设置…)按钮可用。单击它以获取更多设置。

在“Settings”(设置)对话框窗口中,选择“Show install menu”(显示安装菜单),这将会在 Silverlight 上下文菜单中创建一个菜单项。当您运行应用程序并右键单击应用程序时,您会在菜单中看到一个“Install”(安装)菜单项。我稍后会回到这一部分。

现在,勾选“Require elevated trust when running outside the browser”(运行在浏览器外时需要提升的信任)以及如上所示,并将“Window Style”(窗口样式)选择为“No Border”(无边框)。完成这些设置后,单击“OK”保存配置。您也可以在此处更改“Window Title”(窗口标题)、“Size”(大小)和其他可用选项。
设计 XAML 页面
让我们开始设计 XAML 页面来展示我们的示例。在我们的演示示例中,我们将添加三个 TextBox
控件和三个 Buttons
。当应用程序启动时,它将在 TextBox
中填充我们要固定/取消固定到 Windows 7 任务栏的文件的位置(例如,Wordpad、Paint 和 Calculator)。每个 Textbox
旁边都有一个按钮。单击该按钮,它将把应用程序固定到任务栏(前提是应用程序尚未被固定)。如果应用程序已被固定到任务栏,它将从那里取消固定。
以下是我的示例的完整 XAML 代码
<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>
玩转代码
让我们来编写一些代码。首先,我们将用三个不同应用程序(Wordpad、Paint 和 Calculator)的位置填充我们的 TextBox
。请记住,Silverlight 在访问本地文件时有一些限制。因此,在这种情况下,我们将使用一些受信任的位置。
GetFolderPath()
方法将返回“开始菜单”->“所有程序”->“附件”目录,我们将通过附加文件名来设置它作为 TextBox
的值。在设置路径之前,让我们讨论一下方法中的代码行。
- 第一步,我们需要从
AutomationFactory
创建 Shell Application 对象。 - 获得 Shell Application 实例后,我们可以获取通用程序文件夹。我们可以通过将值“
23
”传递给NameSpace
方法来获取它。23
是 Windows 通用程序目录路径的命名空间。我们将它存储在名为“commonPrograms
”的本地动态变量中供以后使用。 commonPrograms.Self.Path
将返回通用程序文件夹的确切路径。- 我们将“
Accessories
”附加到此路径,以便获得必须从中选择应用程序文件的确切位置。
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;
}
}
在页面加载时,我们将调用此方法并将 TextBox
字段填充为确切的位置。这是代码
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");
}
如果您现在运行该应用程序,它看起来会像这样

现在,让我们深入研究实现一个方法,该方法将文件名作为参数,并检查程序是否已固定到任务栏。如果未固定,代码将固定该应用程序;如果已固定,则会取消固定。让我们编写代码
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.");
}
}
}
}
第一行与前面描述的相同。获得 Shell Application 实例后,我们将通过调用 GetFolderPath()
从 shell
命名空间获取附件目录。现在,将带扩展名的文件名附加到整个路径。我们必须使用.lnk 作为扩展名,因为我们是从“开始菜单”文件夹访问它,在该文件夹中所有应用程序都有一个快捷方式链接,即扩展名为.lnk。
获得完整的应用程序路径后,我们可以通过调用 Verbs()
来检索分配给该应用程序的上下文菜单项。现在,我们将遍历每个项并检索项名称
dynamic verb = verbs.Item(i);
string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();
现在我们将检查项名称是否为“pin to taskbar”(固定到任务栏),这意味着应用程序尚未固定到您的任务栏。所以通过调用 verb.DoIt()
将其固定到任务栏。如果项名称是“unpin from taskbar”(从任务栏取消固定),则意味着它已固定到任务栏。因此,我们可以通过再次调用 verb.DoIt()
来取消固定它。调用 verb.DoIt()
实际上会执行 shell 以运行所选的项目命令。
在按钮点击实现中,我们只需通过传递应用程序名称,即“Wordpad”、“Paint”、“Calculator”等来调用此方法,并且在单击时,它将检查名称并执行我们告诉它做的操作。
玩转应用程序
编写应用程序的代码和设计 UI 花费了大量时间。现在让我们运行应用程序,看看我们到目前为止实现了什么。
一旦运行您的应用程序(如果它在浏览器模式下打开,请将其安装为 Silverlight 浏览器外应用程序并在桌面上运行),您将看到以下窗口

单击“Wordpad”应用程序的 TextBox 旁边的“Pin/Unpin”按钮。您会看到 Wordpad 图标已添加到您的 Windows 7 任务栏(前提是该图标尚未被固定),并会提示消息“Wordpad 已固定到您的任务栏。”让我们也对其他按钮做同样的事情。您将看到,当您单击相应的按钮时,应用程序会固定到任务栏。

让我们逐一再次单击按钮。您会注意到,当您单击相应的按钮时,应用程序会逐个从任务栏取消固定,并会提示消息“<APP_NAME>
已从您的任务栏取消固定。”

哇,多么棒的功能!!!是的,这太棒了。我们可以直接从 Silverlight 应用程序(仅限 OOB)访问 Windows 7 任务栏。以前只有 Windows 独立应用程序才有权访问它。现在 Silverlight 也可以了。
历史
- 初始发布 - 2010 年 6 月 18 日
结束语
我认为,通过本文,您对 Silverlight COM API 访问 Windows 7 任务栏有了初步了解。现在您可以考虑在您的业务应用程序中使用 Silverlight 做一些新的事情。还有许多其他功能。不仅如此,您甚至可以访问 Windows 注册表。所以,探索更多 COM API 来满足您的业务需求。
如果您有兴趣,可以下载为本文编写的示例源代码。不仅如此,您甚至可以下载演示 zip 文件。只需运行名为“install”的文件。它将自动安装 Silverlight XAP 应用程序,并在您的桌面和开始菜单中创建应用程序快捷方式。打开文件以执行示例应用程序。
请为本文投票,并不要忘记提供您的反馈/建议。这将给我改进文章的机会。
请在 CodeProject 和 我的博客 上阅读我的文章。