为 Microsoft Windows Vista 和 Server 2008(Windows 7)编程






4.46/5 (30投票s)
本文将介绍 Microsoft Vista 和 Server 2008(以及 Windows 7)的独有功能,这些功能可以使用 C# 等 .NET 语言进行编程。内容包括 UAC、Vista Bridge 控件库和 Windows 搜索提供程序。
引言
在本文中,我将讨论开发 Windows Vista、Windows Server 2008 以及即将推出的操作系统 Windows 7 的应用程序所需了解的知识,以及如何从 .NET (C#) 应用程序中实现这些功能。随附的可下载应用程序包含了立即开始所需的一切。它包括 Vista Bridge 运行时、其 CHM 帮助文件以及 Windows 搜索互操作程序集。但是,为了及时了解 Microsoft 的更新,您应该从 Microsoft 网站获取更新的运行时。
本文将涵盖以下主题:
- Vista Bridge
- 用户账户控制 (UAC)
- 目录结构
- 新控件和对话框
- Windows 搜索
Vista Bridge
Vista Bridge 是 Microsoft 推出的一项新 API,它封装了许多对 Windows Vista 操作系统的本机调用。这使得 Vista 中诸如 Glass 窗体、新对话框等激动人心的功能得以实现。我们将仅限于讨论此 API 所公开的最基本和通用功能。
用户账户控制
UAC 是从 Windows Vista 和 Windows Server 2008 开始独有的功能。尽管它存在一些问题,但该功能使得 Windows Vista 和 Server 2008 比其前代产品更加安全。设想一种情况:用户获得管理员权限并安装了木马程序,从而导致系统不稳定。UAC 功能降低了这种情况发生的可能性。登录为管理员的一般用户在执行需要提升权限的操作时,必须通过 UAC 提示。因此,我们可以推断,在 Windows Vista 上登录为管理员的用户并没有获得管理员权限。
要提供管理员权限,请从上下文菜单中选择“以管理员身份运行”。此部分会将应用程序兼容性标志添加到注册表中,路径为 HCU\Software\Microsoft\Windows NT\Current Version\AppCompatFlags\Layers,值为 RUNASADMIN。
如何获得 UAC 提示并以提升的权限运行应用程序?
要为您的应用程序获取提升的权限,请按照以下步骤操作:
- 向应用程序项目添加清单文件。应用程序清单的默认名称为 app.manifest。
- 打开清单文件,并在 XML 中将
requestedExecutionLevel
的level
属性编辑为代表应用程序执行权限的值。
执行权限值包括 requireAdministrator
、highestAvailable
和 asInvoker
。highestAvailable
值表示应用程序将获得用户拥有的权限——但前提是获得用户同意。requireAdministrator
值需要管理员权限。如果用户未以管理员身份登录,则会出现一个登录对话框,用户可以在其中以管理员身份登录以运行应用程序。asInvoker
值表示应用程序以用户安全令牌运行。
uiAccess
属性指定应用程序是否需要与桌面上的更高权限窗口进行交互。以下代码片段演示了 UACAdminPrompt
的 app.manifest 文件,以获取管理员权限:
<asmv1:assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
xmlns="urn:schemas-microsoft-com:asm.v1" manifestversion="1.0">
<assemblyidentity version="1.0.0.0" name="MyApplication.app">
<trustinfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedprivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedexecutionlevel level="requireAdministrator" uiaccess="false">
</requestedexecutionlevel>
</requestedprivileges>
</security>
</trustinfo>
</assemblyidentity>
盾牌图标
当用户单击带有盾牌图标的控件时,会显示一个提升提示。提升提示会因被提升的应用程序类型而异。
- Windows 需要您的许可才能继续。此提升提示会显示给随 Windows 一起提供的应用程序。
- 一个程序需要您的许可才能继续。此提升提示会显示给包含证书以提供发布者信息的应用程序。
- 一个未知程序想要访问您的计算机。此提升提示会显示给不包含证书的应用程序。
目录结构
从 Windows XP 到 Vista,目录结构发生了很大变化。不再存在 c:\Documents and Settings\<username> 形式的目录,在 Vista 中已被 c:\Users\<username> 取代。Windows XP 为存储用户特定数据定义了一个子目录 My Documents,但 Windows Vista 定义了 c:\Users\<username>\Documents。要检索文件夹路径,请使用 SpecialFolder
枚举,如下所示:
string folderName = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
以下表格描述了 SpecialFolder
枚举定义的一些文件夹:
Content | SpecialFolder 枚举 |
Windows Vista 默认目录 |
---|---|---|
用户特定文档 | 个人 |
c:\Users\<user>\Documents |
用于漫游配置文件的用户特定数据 | ApplicationData |
c:\Users\<user>\AppData\Roaming |
本地化到系统的用户特定数据 | LocalApplicationData |
c:\Users\<user>\AppData\Local |
程序文件 | ProgramFiles |
c:\Program Files |
不同程序共享的 Program Files | CommonProgramFiles |
c:\Program Files\Common |
所有用户共用的应用程序数据 | CommonApplicationData |
c:\ProgramData |
应用程序 DirStucture 项目突出显示了一个使用上述枚举检索 Vista 目录的示例代码。
Windows 搜索提供程序
在开始之前,我需要说明,Windows 搜索服务必须启用才能正常工作。禁用Windows 搜索服务将导致查询失败并返回错误。打开一个 C# 项目,创建一个名为 VistaSearch 的 Windows 窗体应用程序。在设计模式下打开 Windows 窗体,并放置以下控件:
- 名为
tbSearch
的TextBox
- 名为
btnSearch
的Button
,文本:SQL 搜索 - 名为
btnClassicSearch
的Button
,文本:搜索 - 详细模式的
ListView
,名为lvResult
。
Windows 搜索提供了一个 DSO,用于使用 SQL 查询来查询 Windows 搜索引擎。该 DSO 名为 Provider=Search.CollatorDSO.1;EXTENDED PROPERTIES='Application=Windows'。使用 OLEDB 连接打开此提供程序,并将 SQL 查询传递进去以获取结果。
好了,我们已经完成了。现在,让我们看看如何在我们的应用程序中使用这个 DSO。打开与按钮名称 btnSearch
对应的事件处理程序的源代码,然后输入:
try
{
lvResult.Clear();
string indexConnectionString = "Provider=Search.CollatorDSO.1;" +
"EXTENDED PROPERTIES='Application=Windows'";
OleDbConnection connection = new OleDbConnection(indexConnectionString);
connection.Open();
OleDbCommand command = connection.CreateCommand();
command.CommandText = tbSearch.Text;
OleDbDataReader reader = command.ExecuteReader();
DataTable schemaTable = reader.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
{
lvResult.Columns.Add(row[0].ToString());
}
while (reader.Read())
{
ListViewItem item = new ListViewItem(reader[0].ToString());
for (int i = 1; i < reader.FieldCount; i++)
{
item.SubItems.Add(reader[i].ToString());
}
lvResult.Items.Add(item);
}
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
应用程序还必须包含以下行:
using System.Data.OleDb;
以上代码将产生以下输出:
对于那些了解如何使用 SQL 搜索查询数据库的人来说,这应该很容易理解。
高级查询语法 (AQS)
现在,让我们关注问题的第二部分。上面的搜索查询包含了 SQL,但您是否希望您的应用程序用户直接在搜索文本框中输入 SQL?我猜答案是否。因此,解决方法是使用 Vista 内置的基于 COM 的 AQS 助手来完成我们的工作。为此,我们首先必须实现 COM 可调用包装器,如下所示:
tlbimp "c:\Program Files\Microsoft SDKs\Windows\v6.0\Lib\SearchAPI.tlb"
/out:Interop.SearchAPI.dll
如果路径不存在,则有一个替代方案:
tlbimp "c:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\SearchAPI.tlb"
/out:Interop.SearchAPI.dll
输出将是一个名为 Interop.SearchAPI.dll 的 DLL 运行时。从我们的项目中添加对此 COM 包装器 DLL 的引用,然后将以下行添加到源代码中:
using Interop.SearchAPI;
然后,我们将编写一个名为 GetSql
的函数,在该函数中我们仅传递搜索关键字,它将生成 SELECT
SQL 调用语句,我们将其作为 SQL 语句传递给上面编写的代码。
private string GetSql(string aqs)
{
CSearchManager searchManager = new CSearchManager();
CSearchCatalogManager catalogManager = searchManager.GetCatalog("SystemIndex");
CSearchQueryHelper queryHelper = catalogManager.GetQueryHelper();
return queryHelper.GenerateSQLFromUserQuery(aqs);
}
现在,我们可以打开并修改 btnClassicSearch
点击事件的源代码,如下所示:
private void btnClassicSearch_Click(object sender, EventArgs e)
{
try
{
lvResult.Clear();
string indexConnectionString = "Provider=Search.CollatorDSO.1;" +
"EXTENDED PROPERTIES='Application=Windows'";
OleDbConnection connection = new OleDbConnection(indexConnectionString);
connection.Open();
OleDbCommand command = connection.CreateCommand();
command.CommandText = GetSql(tbSearch.Text);
OleDbDataReader reader = command.ExecuteReader();
DataTable schemaTable = reader.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
{
lvResult.Columns.Add(row[0].ToString());
}
while (reader.Read())
{
ListViewItem item = new ListViewItem(reader[0].ToString());
for (int i = 1; i < reader.FieldCount; i++)
{
item.SubItems.Add(reader[i].ToString());
}
lvResult.Items.Add(item);
}
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
有关源代码,请参阅本文提供的 VistaSearch 项目下载。演示输出如下:
Aero Glass 窗体
要设计 Aero 窗体,只需打开一个 C# Windows 窗体应用程序,然后将 VistaBridgeLibrary.dll 和 VistaBridgeControls.dll 添加到您的应用程序中。将以下行添加到您的源代码:
using Microsoft.SDK.Samples.VistaBridge.Dialogs;
现在,使您的 Aero 窗体(待创建)类派生自 GlassForm
超类。然后,修改 Form1_Load
,即 Load
事件,并添加以下行以启用 Aero 功能:
this.IsGlassEnabled = true;
下面显示了一个 Aero 窗体示例:
命令链接
命令链接控件是 Windows Button
控件的扩展。命令链接控件包含一个可选图标和一个注释文本。此控件常用于任务对话框和向导。要使用 Vista 控件,请将以下行添加到 Windows 窗体源代码:
using Microsoft.SDK.Samples.VistaBridge.Controls;
现在,向 Windows 窗体类添加一个 private
变量,如下所示:
private CommandLinkWinForms commandLinkDemo = new CommandLinkWinForms();
现在,修改 Windows 窗体构造函数,将命令链接添加到我们的 Windows 窗体中,如下所示:
InitializeComponent();
commandLinkDemo.NoteText = "This is the Note Text on the Windows Vista type Button";
commandLinkDemo.ShieldIcon = true;
commandLinkDemo.Text = "This Command Link control is a part of Vista Library";
commandLinkDemo.UseVisualStyleBackColor = true;
commandLinkDemo.Location = new Point(20, 20);
commandLinkDemo.Size = new Size(300,100);
commandLinkDemo.Click += new EventHandler(this.OnCommandBtnClicked);
this.Controls.Add(commandLinkDemo);
因此,我们上面看到,项目中还添加了一个 Click
事件处理程序,该处理程序如下:
protected void OnCommandBtnClicked(object src, EventArgs ev)
{
MessageBox.Show("Command Link button clicked.",
"Vista command Link Demo", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
源代码来自 VistaCommandLink 项目,其输出如下:
文件对话框
Windows Vista 已将其新的对话框替换了经典的对话框,这些新对话框内置了 Windows 搜索功能,以简化文件的打开和保存。要显示文件打开对话框,请使用以下代码:
CommonOpenFileDialog dlg = new CommonOpenFileDialog();
dlg.Filters.Add(new CommonFileDialogFilter("All Files.", "*.*"));
CommonFileDialogResult result = dlg.ShowDialog();
上述代码的输出如下:
文件保存对话框使用以下代码显示:
CommonSaveFileDialog dlg = new CommonSaveFileDialog();
dlg.Filters.Add(new CommonFileDialogFilter("All Files", "*.*"));
CommonFileDialogResult result = dlg.ShowDialog();
上述代码的输出如下:
任务对话框
任务对话框是下一代对话框,取代了旧的消息框。任务对话框是新通用控件的一部分。在 Vista 中,可以通过 TaskDialog
类访问它。以下代码显示了一个简单的任务对话框:
TaskDialog.Show("This is a Simple Task Dialog");
上述代码的输出如下:
以下代码设置了任务对话框的成员属性,即 Caption
、Content
、StandardButtons
和 MainIcon
:
TaskDialog dlg = new TaskDialog();
dlg.Caption = "Title";
dlg.Content = "This is some information in the Task Dialog.";
dlg.StandardButtons = TaskDialogStandardButtons.OkCancel;
dlg.MainIcon = TaskDialogStandardIcon.Information;
TaskDialogResult result = dlg.Show();
上述代码的输出如下:
通过任务对话框,您还可以设置命令链接。所以,让我们编写另一段代码,如下所示:
TaskDialog dlg = new TaskDialog();
dlg.Caption = "Title";
dlg.Content = "This is some Content Information in the Task Dialog.";
dlg.StandardButtons = TaskDialogStandardButtons.YesNo;
dlg.MainIcon = TaskDialogStandardIcon.Shield;
dlg.ExpandedText = "This is the Expanded text.";
dlg.ExpandedControlText = "This is the Expanded Control text in the Task Dialog.";
dlg.CollapsedControlText = "This is the content of the collapsed control text.";
dlg.ExpansionMode = TaskDialogExpandedInformationLocation.ExpandFooter;
dlg.FooterText = "This is the footer text.";
dlg.FooterIcon = TaskDialogStandardIcon.Information;
TaskDialogResult result = dlg.Show();
结果是显示一个包含两个窗体的单个对话框:
任务对话框还可以包含其他控件。在下面的代码片段中,我们将创建一个任务对话框,并添加两个单选按钮、一个命令链接和一个进度条控件。
TaskDialog dlg = new TaskDialog();
dlg.Caption = "Title";
dlg.Instruction = "Sample Task Dialog";
TaskDialogRadioButton radio1 = new TaskDialogRadioButton();
radio1.Name = "radio1";
radio1.Text = "One";
dlg.Controls.Add(radio1);
TaskDialogRadioButton radio2 = new TaskDialogRadioButton();
radio2.Name = "radio2";
radio2.Text = "Two";
dlg.Controls.Add(radio2);
TaskDialogCommandLink commandLink = new TaskDialogCommandLink();
commandLink.Name = "link1";
commandLink.ShowElevationIcon = true;
commandLink.Text = "Information";
commandLink.Instruction = "Sample Command Link";
dlg.Controls.Add(commandLink);
TaskDialogMarquee marquee = new TaskDialogMarquee();
marquee.Name = "marquee";
marquee.State = TaskDialogProgressBarState.Normal;
dlg.Controls.Add(marquee);
TaskDialogResult result = dlg.Show();
上述代码的输出如下:
GUIVistaDialog 项目
该项目结合了本文介绍的所有 Vista 对话框。它有一个主要的 Aero 窗体,如下所示:
注意:要使用 Vista 库和 Vista 对话框,您必须添加以下代码行:
using Microsoft.SDK.Samples.VistaBridge.Dialogs;
using Microsoft.SDK.Samples.VistaBridge.Library;
好了,这就是开始一个基于 Windows Vista 的视觉增强项目所需了解的一切。再会。