深入了解 Windows 7

库简介

Yochay Kiriaty

本文讨论:

  • Windows 7
  • 公共文件对话框
  • 外壳程序的编程模型
本文涉及以下技术:
Windows 7

这篇文章基于 Windows 7 的预发布版本。详细信息可能会有变动。

内容

在 Windows 7 中的用户库意味着
库识别应用程序
使用公共文件对话框
选择并使用 Like 文件夹的库
外壳程序的编程模型
使用外壳程序的编程模型
使用新 IShellLibrary API
究的库
支持完全的库模型
摘要

本文是有关 Windows 7 文章的一系列在第一个文章篇。该系列重点若要使 Windows 7 上 shine 其应用程序开发人员可以点击到的新用户体验。本文第一,部分重点介绍调用库的 Windows 7 中一个新用户配置文件存储概念。下载Windows 7 Release Candidate现在以帮助您获取本文一点。

在 Windows 7 中的用户库意味着

之前我们开始深入了解 Windows 7 库 API 我们需要以更好地了解为什么库引入 Windows 7 中以及如何在改善要管理其内容的用户体验。要更好地理解 Windows 7 中的库的概念,我们需要返回查看时间。早期版本的 Windows,Windows Vista 和 Windows XP 包含的特殊文件夹用于存储我的文档类似的用户内容。Windows XP 使用的常量的特殊项目 ID 列表 (CSIDL),即的提供唯一的系统独立于方法标识通常由应用程序的特殊文件夹,但它可能不具有相同的名称或任何给定系统上的位置的值的列表。

在 Windows Vista 时间范围中 CSIDL 发展到新的存储系统称为已知的文件夹 ID。为 Windows Vista,的 CSIDL 特殊文件夹引用由一组 GUID 值。值得注意 CSIDL 系统仍然不支持 Windows Vista 和用于 Windows 7 中向后兼容性。在已知的文件夹 ID 列表中可以找到 FOLDERID_Documents 文件夹。此文件夹代表同时的 My Documents 文件夹作为用户存储配置文件的一部分和作为系统的特殊文件夹的一部分 FOLDERID_Fonts。在 Windows 7 以支持 Windows 7 库将展开已知的文件夹 ID 的列表。您可以找到有,此外,像在 FOLDERID_DocumentsLibrary 代表在文档库的 GUID。在 Windows Vista 中这些特殊文件夹自动索引以允许用户执行其内容的更快、 更高效的搜索操作中。但是,我们发现以各种形式的很多用户存储文件置于其 PC,在"特殊"用户配置文件文件夹中不仅 c 的 Temp 文件夹类似的不同文件夹中 d:\Birthday2008\pictures,或甚至在远程存储中。存储用户配置文件存储空间之外的文件影响该索引的会影响搜索经验的用户。我们经常发现自己查找我们从事只需几天前,忘记我们保存它的特定文件,然后发现,搜索无法找到它,因为该文件永远不会索引。

与 Windows 7 库的概念尝试解决该问题的从而存储都通过其计算机的内容的用户具有在文档库文件夹结构的完全控制权。换句话说,Windows 7 中的用户可以定义要在文档库中包含的文件夹。实际上,这适用于 Windows 7 中的任何库。我们只能说库是用户定义的用户的内容的逻辑表示的文件夹集合。通过在库中包括文件夹,用户告知 Windows 他或她的重要数据的位置。系统将索引启用快速搜索和 Windows 资源管理器中的功能根据文件属性和元数据更丰富查看排列在这些文件夹。图 1 显示多个文件夹的集成到单个库视图,并在 Windows 7 显示格式的搜索和 Windows 资源管理器的透视。

fig01.gif

图 1 集成到单个库的多个文件夹的查看

库是 Windows 外壳程序的组成部分。此集成是非常重要的原因,用户可以像在一个文件夹这意味着用户需要了解任何新的行为相同的方式浏览他们的文件。单击文档库只会显示一个特定的排列方式中所有文档。此外,因为的库集成到 Windows Shell,用户可以执行搜索操作并通过使用属性和元数据筛选结果,如日期图片拍摄,该的歌曲流派和项目的普及。换句话说,使用库用户获得欣赏灵活且索引的文件存储。

库识别应用程序

我们想要注意大多数应用程序应该可以正常工作与 Windows 7 库时, 有是引入 Windows 7 库环境以提供更丰富的用户体验的机会。一个可能想知道会发生如果应用程序不支持库。假设的应用程序,作为它的功能的一部分需要将文件保存到磁盘。应用程序将提示保存用户使用为该文件选择一个位置选项。由于这是用户通常访问他或她需要使用某个文档时,用户可能会保存"位置,"选择他或她在文档库。

但是,如果应用程序不能识别文档库不是普通文件夹,应用程序将尝试保存该文件向文档库直接像是磁盘上的另一个文件夹。这表示问题,因为现在,我们已经知道库是 non–file 系统位置并且因此不能被视为常规文件夹。应用程序需要成为知道的处理库的。幸运的是,Windows 7 包括更新的外壳程序 API、 库 API,和更新使开发人员能够正确处理库的公共文件对话框。

库支持应用程序应包含用于处理情况下,用户无意中尝试为如果它们是用于将文件保存到库或加载库的内容的文件夹中选择库的机制。此外,大多数应用程序使用户可以作为应用程序体验的一部分与文件系统进行交互。应用程序应提供具有相同的熟悉的入口点的用户,并由 Windows 7 库提供的用户界面。通过文件夹中用户指定他们的重要数据的存储位置,库,告诉我们这内容他们关心。应用程序应通过其应用程序中支持库升级这些位置。

对于开发人员,有与 Windows 7,可帮助应用程序变得库支持的几个集成点。开发人员进行复查下面的三个集成点,和根据其需要进行选择。

  1. 大多数的基本的集成点是只是使用公共文件对话框 (CFD) 选择文件和文件夹,并保存直接到库。
  2. 第二个集成点提供应用程序通过启用应用程序来选择和使用库内容 shine Windows 7 上该选项。
  3. 最后一个集成点提供更多的高级集成选项,支持完整的库编程模型。

使用公共文件对话框

好消息是 Windows 7 库的第一个类在种 CFD 使用户可以浏览和搜索库中的员工。他们甚至可以选择为保存特定库的不只是之一库,但而不是库自身中文件夹的位置 !因为 Windows 7 库是存储备份,用户可以在保存,并将文件复制到他们具有权限的一个库中包含的任何文件夹。每个库都有默认保存位置的用户复制时,文件的位置,并保存直接对库的文件。默认,此位置将默认的库中包含的已知的文件夹或第一个文件夹添加到自定义库。

但是 (没有始终此 caveat !),强烈建议使用 Windows Vista 和不是旧版本,CFD 的引入的新 CFD 界面。很注意使用旧版 CFD 的 API 没有因为 Windows Vista 和 Windows XP,更改出于应用程序兼容性的原因非常重要。但是,在 CFD 的旧版本不直接支持库,或完全新的用户体验提供 Windows 7 中。图 2 显示在旧式和新 CFD 并排。

fig02a.gif

fig02b.gif

图 2 的新的公共文件对话框的旧的和新视图

在旧的 CFD 在即使右导航窗格中显示的库它们将需要的额外单击将保存到包含文件夹而不是只是库自身之一。用户既不在 CFD 内搜索直接从或遇到格式的预览处理程序也在文件夹,选择多个文件,因为旧 CFD 不支持从不同的文件夹位置中返回多个文件。相反,这是 Windows 7 库支持的方案。

值得使用正确的 API 来显示该 CFD 的正确版本。方面显示一个 CFD 使用.NET 开发人员可以使用该 System.Windows.Forms.FileDialog 或 Microsoft.Win32.FileDialog 命名空间。因为后一个使用该的 CFD 旧版.NET 开发人员应始终使用 WinForms 命名空间以显示新 CFD。图 3 显示了代码段,提示用户来选择保存显示公共位置保存文件对话框,使用户能够选择文件夹或库。

图 3 SaveFileDialog 文件

System.Windows.Forms.SaveFileDialog _fd = new System.Windows.Forms.  SaveFileDialog();
_fd.Title = "Please choose a location to save your file";
_fd.FileName = "[Get Folder…]";
_fd.Filter = "Library|no.files";
if (_fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
    string dir_path = System.IO.Path.GetDirectoryName(_fd.FileName);
    if (dir_path != null && dir_path.Length > 0)
    { 
        lblResult.Content = dir_path; 
    }
}

本机代码开发人员应使用 IFileDialog 本机 API 在新系列: IFileDialog,IFileOpenDialog,IFileSaveDialog,IFileDialogCustomize,IFileDialogEvents,IFileDialogControlEvents。 这些替换早期 Windows 版本中旧的 API: GetOpenFileName,GetSaveFileName。

图 4 显示如何使用新系列的 IFileDialog 本机 API 来提示用户使用保存对话框将保存到一个文件夹 / 库。

图 4 IFileDialog 本机 API

*ppsi = NULL;
IFileSaveDialog *pfod;
hr = CoCreateInstance(
CLSID_FileSaveDialog, 
NULL, 
CLSCTX_INPROC, 
IID_PPV_ARGS(&pfod));
if (SUCCEEDED(hr))
{
  hr = pfod->SetOptions(FOS_PICKFOLDERS);
  if (SUCCEEDED(hr))
  {
  hr = pfod->Show(hWndParent);
           if (SUCCEEDED(hr))
           {
           hr = pfod->GetResult(ppsi);
           }
    }
    pfod->Release();
}

外壳程序本机 API 是基于 COM 的。 使用任何 COM 对象之前,我们需要通过调用 CoCreateInstance 初始化 COM 对象。 初始化之后,* pfod IFileSaveDialog 变量,我们设置对话框选项,通过将 FOS_PICKFOLDERS 标志传递给该 IFileOpenDialog.SetOptions() 选择文件夹。 此代码告诉打开对话框以使用户能够选择文件夹,而不是文件,并允许用户选择一个库中的,保存位置。 在选择库的情况下,CFD 然后将返回默认的保存位置文件夹与所选的库关联。

图 3 和 图 4 非常简单,并不引入任何新代码。 但是,很重要提升应用程序运行在 Windows 7 和支持的 Windows 7 库之间的一致性。 在 CFD 旨在与包括库新到的 Windows Explorer 提供一致的体验。 Windows 7 资源管理器中的所有改进了被都带入在 CFD。 在大多数的情况下是用户浏览和交互中的库应用程序内的理想方式。

选择并使用 Like 文件夹的库

假设向用户显示图片的幻灯片应用程序的案例。 通过库用户实质上告诉系统他 (或她的重要图片存储在该图片库中。 应用程序可以只需直接指向图片库和显示给用户的图片的整个集合。 此外,点的视图中的开发人员,使用库系统可以消除维护单独的配置文件或图片,是例如的数据库,因为开发人员可以依靠库系统的必要性。 我们深入编程 API 的外壳程序库之前,我们需要了解有关外壳程序的编程模型的几个概念。

外壳程序的编程模型

外壳程序项 (IShellItem),通常称为项目,都是外壳 UI 的货币和的编程模型。 项是单个、 独立的内容源。 是例如相当的几个用于控制 CFDs 接口方法将使用外壳项目指向文件夹,而文件系统路径。 原因是重要在 CFD 可以交流有关文件系统文件夹和在外壳程序如控制面板或计算机文件夹中找到的其他虚拟文件夹的信息。

其他重要的外壳程序 COM 接口是:

  • IShellLink 接口代表通常到文件、 文件夹,或可执行文件的一个链接
  • IShellFolder 接口在外壳程序命名空间表示 Shell 文件夹对象。 使用文件夹的内容可以遍历的 IShellFolder,检索文件夹中的项目的显示名称、 分析 relative to 文件夹的显示名称和获取的项目 ID 列表

Windows 7 引入了称为 IShellLibrary 新外壳程序 API,您可以查询从 IShellItem 以工作,并支持 Windows 7 中的库。

现在,外壳编程模型的不同组件我们定义我们可以看到库如何适应此模型。 因为库不是文件系统位置,不能使用文件 system–specific FindFirstFile 类似的 API。 相反,您必须使用库的内容的两个主要选项。

使用外壳程序的编程模型

可以使用 IShellItem 和 IShellFolder 接口和数量的帮助器函数来枚举的库,内容就像它们是常规文件夹。 这意味着应用程序可以使用库的内容,而无需使用新库 API 和很少更改其现有基本代码。

图 5 显示如何使用 IShellFolder 接口来枚举此图片库的整个内容。

图 5 IShellFolder 接口

IShellItem *psi;
HRESULT hr =  SHGetKnownFolderItem(FOLDERID_PicturesLibrary, KF_FLAG_CREATE, NULL, IID_PPV_ARGS(&psi));
if(SUCCEEDED(hr))
{
    IShellFolder *psf;
    hr = psi->BindToHandler(NULL, BHID_SFObject | , IID_PPV_ARGS(&psf));
    if(SUCCEEDED(hr))
         {
               IEnumIDList *penumIDList;
               psf->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS , IID_PPV_ARGS(&penumIDList));
               //use penumIDList to enumerate the content of the folder
          }
}

您可以看到,使用帮助器函数 SHGetKnownFolderItem 我们可以通过在 FOLDERID_PicturesLibrary 中检索库的正确位置。 这是一个表示已知的文件夹它在本例中是图片库的 GUID。 成功调用将填充此 IShellItem * 具有正确信息有关该的库的 Psi 接口表示为一个外壳程序项。 代码的其余由编程,我们可以使用在 BindToHandler 绑定之前获取的外壳项目到外壳程序文件夹 (强制转换) 的标准外壳程序。 接下来,我们枚举该外壳程序为文件夹,在库的情况下可以是文件或文件夹中的在不同的项目。 在 SHGetKnownFolderItem 将是外壳程序帮助器函数,并且是帮助器函数可以找到 Windows 7 RC SDK 中 Shlobj.h 头文件中的一大组的一部分。 请注意,SHCONTF_FOLDERS | 我们传递的 SHCONTF_NONFOLDERS 标志。 这在库中告诉 Shell 文件夹,我们要返回的所有文件和文件夹。 我们可以传递 SHCONTF_NAVIGATION_ENUM 来获取库位置而不是库内容。

使用新 IShellLibrary API

可以实现相同的功能中显示 图 5 使用新 Windows 7 IShellLibrary API 中所示 图 6 .

图 6 IShellLibrary API

IShellLibrary *pslLibrary;
HRESULT hr = SHLoadLibraryFromKnownFolder(FOLDERID_PicturesLibrary, STGM_READ, IID_PPV_ARGS(&pslLibrary));
if(SUCCEEDED(hr))
{
       IShellItemArray *psiaFolders;
       hr = pslLibrary->GetFolders(LFF_STORAGEITEMS, IID_PPV_ARGS(&psiaFolders)); 
       IEnumShellItems *penumShellItems;
       psiaFolders->EnumItems(&penumShellItems);
       //work with penumShellItem to enumerate the items in the library
}

您可以看到我们使用另一个帮助器函数 SHLoadLibraryFromKnownFolder,创建 IShellLibrary 对象。 从此对象中,我们可以调用 GetFolders 方法可返回一个 IShellitemArray。 此返回被更高版本用于获取来遍历整个内容库的枚举器。

在上一个示例,我们使用帮助器函数,SHLoadLibraryFromKnowFolder。 如上所述,此 Helper 函数等等与 Windows 7 库,可以找到 Shlobj.h 头文件中 Windows 7 RC SDK 中。 下面是重要的库帮助器函数的列表:

  • SHAddFolderPathToLibrary (向库中添加一个文件夹)
  • SHCreateLibrary (创建 IShellLibrary 对象)
  • SHLoadLibraryFromItem (创建和从指定的库定义文件中加载 IShellLibrary 对象)
  • SHLoadLibraryFromKnownFolder (创建和指定的 KNOWNFOLDERID 的加载 IShellLibrary 对象)
  • SHLoadLibraryFromParsingName (创建和加载一个 IShellLibrary 对象,用于指定的路径)
  • SHRemoveFolderPathFromLibrary (从库中, 删除一个文件夹)
  • SHResolveFolderPathInLibrary (尝试解决一个库文件夹,已移动或重命名的目标位置)
  • SHSaveLibraryInFolderPath (将 IShellLibrary 对象保存到磁盘)

让我们查看下面的代码 ( 图 7 ) 的使用这些帮助器函数的几个创建新库,与该库,关联一个文件夹,然后库"保存"库文件夹中。

图 7 IShellLibrary 使用 SHCreateLibrary Helper 函数

IShellLibrary *pIShelLibrary;
HRESULT hr = SHCreateLibrary(IID_PPV_ARGS(&pIShelLibrary));
if (SUCCEEDED(hr))
{
      IShellItem *pIShellItem;
      SHAddFolderPathToLibrary(pIShelLibrary, L"C:\\Users\\Public\\Documents");
      hr = pIShelLibrary->SaveInKnownFolder(FOLDERID_Libraries, L"My New Library", LSF_MAKEUNIQUENAME, 
            &pIShellItem);
      pIShellItem->Release();
      pIShelLibrary->Release();
}

您可以看到我们要创建新的使用 SHCreateLibrary Helper 函数的 IShellLibrary 对象。 接下来我们将公共文档文件夹添加到库对象。 然后我们将新库保存与该的库的其余部分在库文件夹,并给出该名称我新库。

图 7 中,,我们使用 IShellLibrary 接口的 SaveInKnownFolder 方法保存我们刚刚创建的新库。 大多数 IShellLibrary 界面中的这些方法都是容易理解。 但是,一下某些需要我们注意:

  • Commit 方法提交到现有的库文件的库更改。 这意味着以编程方式更改库时需要调用 Commit 方法以保存所做的更改。
  • 在 SetIcon 方法将设置库图标一个资源 DLL 名称和图标索引。
  • 在 SetFolderType 作为输入的参数接收已知的文件夹的类型模板的 GUID。 此 GUID 定义此库可以是下列之一的类型: 泛型,图片,音乐,视频和文档。 设置该文件夹类型的模板更改库的 Windows 资源管理器视图,并启用搜索和专为库类型的可用视图选项。

究的库

图 7 所示,代码将创建一个新的库文件,其中库文件夹中。 作为具有.library 毫秒的文件扩展名的 XML 定义文件存储在 Windows 7 库。 文件名是库的实际名称。 是例如文档库由 XML 文件名为 documents.library 毫秒表示。 库描述保存在磁盘 %appdata%\Microsoft\Windows\Libraries 文件夹 (也称为 FOLDERID_Libraries) 中上。

让我们深入文档库定义文件架构。 XML 结构是相当容易理解,但让我们来解释其元素的几个。 如 图 8 所示,在文件顶部我们可以找到该库"标题"信息:

图 8 文档库定义文件架构

<libraryDescription xmlns="https://schemas.microsoft.com/windows/2009/  library">
  <name>@shell32.dll,-34575</name>
  <ownerSID>S-1-5-21-2127521184-1604012920-1887927527-4897363</ownerSID>
  <version>4</version>
  <isLibraryPinned>true</isLibraryPinned>
  <iconReference>imageres.dll,-1002</iconReference>
  <templateInfo>
    <folderType>{7D49D726-3C21-4F05-99AA-FDC2C9474656}</folderType>
  </templateInfo>

根 XML 元素是包含如下所示定义库的子元素的 libraryDescription:

  • <ownersid> 定义创建此库,找出库,并防止其他用户的用户数据的用户的安全 ID。
  • <islibrarypinned> 是一个 Boolean 类型的元素,定义如果库被固定在 Windows 资源管理器在左侧的导航窗格并不是任务栏。
  • <version> 定义此库后者反映的库定义文件已被更改的次数的内容的版本。
  • 用于控制在 Windows 资源管理器中的视图的排列,<templateinfo> 是可选的容器元素允许作者指定文件夹类型 (文档、 图片、 视频)。
  • <iconreference> 定义使用标准的 Windows 外壳程序资源样式的图标资源。 例如:

<iconreference> C:\Windows\system32\imageres.dll,-65 </iconreference>。

此图标显示在库中的 Windows 资源管理器。

用户不能更改默认库图标,通过 Windows Explorer,也可以在指定图标到新的自定义用户定义库。 但是,此可以使用该 API 我们将介绍在此系列的未来部分中以编程方式。

XML 的一个关键部分是库如以下代码所示代表的位置的列表:

<searchConnectorDescriptionList>
    <searchConnectorDescription publisher="Microsoft" product="Windows">
      <description>@shell32.dll,-34577</description>
      <isDefaultSaveLocation>true</isDefaultSaveLocation>
      <isSupported>true</isSupported>
      <simpleLocation>
        <url>knownfolder:{FDD39AD0-238F-46AF-ADB4-6C85480369C7}</url>
      <serialized>MBAAAE…. </serialized>
      </simpleLocation>
    </searchConnectorDescription>
  • <searchconnectordescriptionlist> 包含一个或多个搜索连接器将映射到库中包含的物理位置。
  • <searchconnectordescription> 包含 simpleLocation 元素描述在库中包括的一个位置。
  • <url> 定义为此位置的 URL。为人类的可读性仅,这不能由开发人员因为它是可能会过期。
  • <serialized> 将是位置的序列化的 ShellLink 对象的库中的实际表示形式。

最后要注意: 应用程序应该永远不会尝试访问或编辑库说明文件。相反,应用程序应始终使用编程模型或 IShellLibrary API 外壳程序来使用,和操作库内容。

支持完全的库模型

用户可以添加、 删除,重新排列位置,以及更改默认的保存位置通过库管理 UI。这将显示 图 9 ,可直接从 Windows 资源管理器。

fig09.gif

图 9 库管理 UI

此外,还可以通过 IShellLibrary 界面修改库位置。对库结构的任何更改会反映到库定义文件中,而保留直接对基础.library ms 文件中。您可以将通知类更改的通过监视对.library ms 文件的任何更改。假定您的应用程序依赖一个的库的内容,或您的应用程序当前显示给定的库的内容。您希望库的内容更改后得到通知。要获得关于库定义文件的更改通知的应用程序可以这样使用本机 SHChangeNotifyRegister 外壳程序帮助器函数或使用托管的 FileSystemWatcher System.IO 命名空间中找到。由于这些不是新的 API,并且还介绍,使用这些接口本文的范围超出了。

请考虑的另一个选项才的这样应用程序需要管理与添加到图片存储库的新图片的文件夹类似的用户的文件夹。如果您使用图片库可以显示相同的对话框 Windows 7 提供管理其库的用户在您的应用程序中使用库管理对话框。这样做您保留一个一致的外观和用户增大到喜欢的行为。如果您选择使用库管理对话框界面,像您已修改库内容,直接在 Windows 资源管理器中的,将进行对库进行改动。此对话框不会返回到您的应用程序的任何信息。如果您正在显示给定库的内容,将要注册以接收更新,如上面所述的通知。

摘要

此文章中, 被引入概念和 Windows 7 中的库的编程模型。检查库播放作为 Windows 7 用户体验的一部分的重要角色。然后获取深度的深入到库,了解库和浏览支持基础体系结构。然后您会看到不同的商机的开发人员,使他们的应用程序库支持。最后,了通过短浏览其他可用的编程模型和 API。

Yochay Kiriaty 是在 Microsoft,关注 Windows 7 技术的推广者。他在软件开发中都有超过一十年的经验。他已编写,告诉 Academic 计算机科学 courses 和是为一个活动参与者Windows 博客 .

Alon Fliess 是 CTO Sela 组。Sela 已中成功的一个 18 年跟踪记录 IT 培训,和被视为高质量的训练中以色列已经领导者 IT 人员。Alon 有深入了解计算机技术,并且包含一个 bsc 学位电气和计算机工程从 Technion,在以色列 Institute of Technology。已编程和过去讲授 Alon 22 个年,许多 Microsoft 技术尤其是 Windows 内部结构、 C++ Win 32 编程和使用 C# 或 C+ 的.NET 方面的专家 C++/CLI CLI。