65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.46/5 (30投票s)

2009年4月17日

CPOL

8分钟阅读

viewsIcon

64526

downloadIcon

689

本文将介绍 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 提示并以提升的权限运行应用程序?

要为您的应用程序获取提升的权限,请按照以下步骤操作:

  1. 向应用程序项目添加清单文件。应用程序清单的默认名称为 app.manifest
  2. 打开清单文件,并在 XML 中将 requestedExecutionLevellevel 属性编辑为代表应用程序执行权限的值。

执行权限值包括 requireAdministratorhighestAvailableasInvokerhighestAvailable 值表示应用程序将获得用户拥有的权限——但前提是获得用户同意。requireAdministrator 值需要管理员权限。如果用户未以管理员身份登录,则会出现一个登录对话框,用户可以在其中以管理员身份登录以运行应用程序。asInvoker 值表示应用程序以用户安全令牌运行。

uiAccess 属性指定应用程序是否需要与桌面上的更高权限窗口进行交互。以下代码片段演示了 UACAdminPromptapp.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 目录的示例代码。

DirStructure Project

Windows 搜索提供程序

在开始之前,我需要说明,Windows 搜索服务必须启用才能正常工作。禁用Windows 搜索服务将导致查询失败并返回错误。打开一个 C# 项目,创建一个名为 VistaSearch 的 Windows 窗体应用程序。在设计模式下打开 Windows 窗体,并放置以下控件:

  • 名为 tbSearchTextBox
  • 名为 btnSearchButton,文本:SQL 搜索
  • 名为 btnClassicSearchButton,文本:搜索
  • 详细模式的 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 Search

对于那些了解如何使用 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 项目下载。演示输出如下:

Vista Search with Keyword

Aero Glass 窗体

要设计 Aero 窗体,只需打开一个 C# Windows 窗体应用程序,然后将 VistaBridgeLibrary.dllVistaBridgeControls.dll 添加到您的应用程序中。将以下行添加到您的源代码:

using Microsoft.SDK.Samples.VistaBridge.Dialogs;

现在,使您的 Aero 窗体(待创建)类派生自 GlassForm 超类。然后,修改 Form1_Load,即 Load 事件,并添加以下行以启用 Aero 功能:

this.IsGlassEnabled = true;

下面显示了一个 Aero 窗体示例:

AERO Form

命令链接

命令链接控件是 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 项目,其输出如下:

Vista Command Link

文件对话框

Windows Vista 已将其新的对话框替换了经典的对话框,这些新对话框内置了 Windows 搜索功能,以简化文件的打开和保存。要显示文件打开对话框,请使用以下代码:

CommonOpenFileDialog dlg = new CommonOpenFileDialog();
dlg.Filters.Add(new CommonFileDialogFilter("All Files.", "*.*"));
CommonFileDialogResult result = dlg.ShowDialog();

上述代码的输出如下:

Vista Open File Dialog

文件保存对话框使用以下代码显示:

CommonSaveFileDialog dlg = new CommonSaveFileDialog();
dlg.Filters.Add(new CommonFileDialogFilter("All Files", "*.*"));
CommonFileDialogResult result = dlg.ShowDialog();

上述代码的输出如下:

Vista Save File Dialog

任务对话框

任务对话框是下一代对话框,取代了旧的消息框。任务对话框是新通用控件的一部分。在 Vista 中,可以通过 TaskDialog 类访问它。以下代码显示了一个简单的任务对话框:

TaskDialog.Show("This is a Simple Task Dialog");

上述代码的输出如下:

Simple Information Dialog

以下代码设置了任务对话框的成员属性,即 CaptionContentStandardButtonsMainIcon

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();

上述代码的输出如下:

Information Task Dialog

通过任务对话框,您还可以设置命令链接。所以,让我们编写另一段代码,如下所示:

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();

上述代码的输出如下:

Control Task Dialog

GUIVistaDialog 项目

该项目结合了本文介绍的所有 Vista 对话框。它有一个主要的 Aero 窗体,如下所示:

Vista Dialog

注意:要使用 Vista 库和 Vista 对话框,您必须添加以下代码行:

using Microsoft.SDK.Samples.VistaBridge.Dialogs;
using Microsoft.SDK.Samples.VistaBridge.Library;

好了,这就是开始一个基于 Windows Vista 的视觉增强项目所需了解的一切。再会。

© . All rights reserved.