概覽
Windows 7介紹了一種庫的新概念,用戶數據的新的入口點。用戶可以輕松的以集合數據的方式,找到並且管理他們的數據,而且這些數據可能是在計算機中的多個不同的位置。這個庫代替了早期Windows版本中的固有文件夾(比如,我的文檔,圖片,音樂),並且把它們都放入了主“storage”。Shell庫的 API,提供給應用程序一種簡單的方法來對該庫進行交互操作。應用程序可以創建,交互並且像他們的環境中的一級元素一樣支持該庫。
在Windows 7中,Shell庫的概念就是,通過允許他們對其文檔庫文件夾結構的全部控制權限,試圖去解決用戶在他們的PC上,到處存放數據的問題。換而言之,在 Windows 7中,用戶可以在文檔庫中來定義哪個文件夾用來存放。我們也可以說,Shell庫是一種用戶自定義的,合理的代表用戶數據的文件夾集合。在庫中所包含的文件夾,其實就是用戶告訴了Windows,他的或者她的重要數據在哪裡存放。那麼系統將為這些文件夾進行索引,來更快的查詢檢索、在基於文件屬性和元數據的Windows Explorer中具有更豐富的視圖展示能力。
在早期的Windows版本中,每一個應用程序都有其屬於自己的屬性庫。比如,Windows Media Player與iTunes相比,擁有不同的作用域集合,並且兩者都不是與Music文件夾一致的。使用Shell庫的API,應用程序就可以定義並且共同使用用戶自定義的那個區域。
圖例 1
與Windows Shel整合的庫l
Shell庫中同樣也可以包含網絡文件夾。這個功能將給用戶無論是在家還是在單位,都有一個很好的用戶體驗。無論何時用戶打開一個文件對話框,他就能獲得所有可用的庫的指向的集合視圖。
注意 : 了解更多的信息,參考 Inside Windows 7: Introducing Libraries。
目標
在本次動手實驗中,你將了解到如何用編程的方式管理庫;特別是:
• 創建新的庫
• 打開現有的庫
• 在庫中進行添加和刪除文件夾
• 獲取庫文件夾列表
• 刪除庫
• 重命名庫
• 為庫設置一個默認保存文件夾
• 設置庫的屬性,比如文件夾類型,圖標,鎖定到導航欄的狀態等
• 顯示"manage user interface"對話框
安裝
為了方便起見,你在本次動手實驗中所使用到的絕大多數代碼都做成了Visual Studio的代碼片段。所以只需要去安裝實驗中相應的代碼片段就可以了:
1.在實驗的Setup目錄下,運行ShellLibrariesLab.vsi安裝包。
2.跟隨向導說明,安裝代碼片段。
系統需求
完成本實驗,你需要有以下組件:
• Microsoft Visual Studio 2008
• Windows 7
• Windows API Code Pack library
注意 :為了更加簡單,你可以在本實驗的Assets目錄下,找到所有這些集合。但是如果你想更深的挖掘Windows API 代碼包中的資源代碼,請從上面所提到的鏈接頁面中下載。
練習 1: 開發 SLUtil
Shell庫實用工具(SLUtil)是一個用來管理在默認的庫目錄下的庫的命令行工具。
SLUtil 命令:
命令提示
SLUtil Create LibraryName
SLUtil Delete LibraryName
SLUtil Rename OldName NewName
SLUtil AddFolder LibraryName FolderPath
SLUtil RemoveFolder LibraryName FolderPath
SLUtil ShowInfo [LibraryName]
SLUtil FolderType LibraryName [Documents|Pictures|Music|Videos]
SLUtil SaveFolder LibraryName [FolderPath]
SLUtil NavPanePinnedState LibraryName [TRUE|FALSE]
SLUtil Icon LibraryName [Icon]
SLUtil ManageUI Videos
SLUtil ? [CommandName]
任務 1 – 創建 SLUtil 項目
1.啟動 Visual Studio 2008 然後選擇 Console Application 項目模板,選擇你需要使用的語言 (Visual C# 或者 Visual Basic)。鍵入 SLUtil 作為新項目的名稱。
2.添加一個 Microsoft.WindowsApiCodePack.dll 和 Microsoft.WindowsApiCodePack.shell.dll的引用。你也可以在本實驗的Asset文件夾下找到所有的這些程序集。
3.(只對C# 用戶有效)同時添加下面程序集的引用:
PresentationCore
PresentationFramework
WindowsBase
System.Windows.Forms
4.在項目中添加CommandLineInterpreter.cs (C#) 或 CommandLineInterpreter.vb (Visual Basic)文件。你可以在Asset\SLUtil文件夾中找到這個文件,選擇你所使用的語言。
注意:命令行解釋器是一個實用工具類,它知道如何解釋命令行和執行包含CommandAttribute 屬性的靜態方法。
5.To activate the Command Line Interpreter, change the Main method to this code:
(Code Snippet – Shell Libraries – Main CSharp)要激活命令行解釋器,將Main方法中的代碼變為下面的代碼:(代碼片段– Shell Libraries –Csharp模式)
C#
class Program
{
static int Main(string[] args)
{
CommandLineInterpreter cli = new CommandLineInterpreter(args);
return cli.Execute();
}
}
(代碼– Shell Libraries –VB模式)
Visual Basic
Module Module1
Function Main() As Integer
Dim cli As New CommandLineInterpreter(My.Application.CommandLineArgs.ToArray())
Return cli.Execute()
End Function
End Module
6.編譯解決方案。
7.想要測試應用程序的當前狀態,在項目屬性的調試面板中添加一個命令行變量。
圖例 2
添加一個命令行變量
8.使用組合鍵CTRL+F5來執行應??程序。你應該能夠得到下面的輸出結果:
命令
SLUtil ? [CommandName]
Press any key to continue ...
任務 2 –添加Create 命令
ShellLibrary這個Windows API包,包含了許多允許你創建新的庫的構造函數:ShellLibrary:
C#
// Summary:
// Creates a shell library in the Libraries Known Folder,
// using the given IKnownFolder
//
// Parameters:
// kf: KnownFolder from which to create the new Shell Library
// isReadOnly:
public ShellLibrary(IKnownFolder kf, bool isReadOnly);
//
// Summary:
// Creates a shell library in the Libraries Known Folder,
// using the given shell library name.
//
// Parameters:
// libraryName: The name of this library
// overwrite: Override an existing library with the same name
public ShellLibrary(string libraryName, bool overwrite);
// Summary:
// Creates a shell library in a given Known Folder, using the given shell
// library name.
// Parameters:
// libraryName: The name of this library
// kf: The known folder
// overwrite: Override an existing library with the same name
public ShellLibrary(string libraryName, IKnownFolder kf, bool overwrite);
// Summary:
// Creates a shell library in a given local folder, using the given shell
// library name.
// Parameters:
// libraryName: The name of this library
// folderPath: The path to the local folder
// overwrite: Override an existing library with the same name
public ShellLibrary(string libraryName, string folderPath, bool overwrite);
Visual Basic
' Summary:
' Creates a shell library in the Libraries Known Folder,
' using the given IKnownFolder
'
' Parameters:
' kf: KnownFolder from which to create the new Shell Library
' isReadOnly:
Public Sub New(ByVal kf As Microsoft.WindowsAPICodePack.Shell.IKnownFolder, ByVal isReadOnly As Boolean)
' Summary:
' Creates a shell library in the Libraries Known Folder,
' using the given shell library name.
'
' Parameters:
' libraryName: The name of this library
' overwrite: Override an existing library with the same name
Public Sub New(ByVal libraryName As String, ByVal overwrite As Boolean)
' Summary:
' Creates a shell library in a given Known Folder, using the given shell
' library name.
' Parameters:
' libraryName: The name of this library
' kf: The known folder
' overwrite: Override an existing library with the same name
Public Sub New(ByVal libraryName As String, ByVal kf As Microsoft.WindowsAPICodePack.Shell.IKnownFolder, ByVal overwrite As Boolean)
' Summary:
' Creates a shell library in a given local folder, using the given shell
' library name.
' Parameters:
' libraryName: The name of this library
' folderPath: The path to the local folder
' overwrite: Override an existing library with the same name
Public Sub New(ByVal libraryName As String, ByVal folderPath As String, ByVal overwrite As Boolean)
ShellLibrary實現了一個Idispose接口。調用Dispose()方法來釋放Shell庫中的COM對象是非常重要的。我們可以使用using語句來幫助調用。使用一個庫對象的方式如下:
C#
using (ShellLibrary library = new ShellLibray("Library Name", true))
{
//Use the library instance here
}
Visual Basic
Using library As New ShellLibray("Library Name", True)
'Use the lib instance here
End Using
1.創建一個叫做ShellCommands的靜態類(C#)或者一個模塊(Visual Basic)。
2.添加下面的代碼引用其命名空間:
C#
using Microsoft.WindowsAPICodePack.Shell;
Visual Basic
Imports Microsoft.WindowsAPICodePack.Shell
創建一個叫做Create的新的命令。如果要做這項操作,將下面的代碼添加到ShellCommands中(代碼片段– Shell 庫– CreateCommand CSharp):
C#
[Command(
Name = "Create",
Usage = "SLUtil Create LibraryName",
Info = "Create a new library",
Example = "SLUtil Create MyLib")]
public static void CreateLibrary(string name)
{
using (ShellLibrary library = new ShellLibrary(name, true))
{
}
}
(代碼片段– Shell Libraries – CreateCommand VB)
Visual Basic
<Command(Name:="Create", Usage:="SLUtil Create LibraryName", Info:="Create a new library", Example:="SLUtil Create MyLib")> _
Public Sub CreateLibrary(ByVal name As String)
Using library As New ShellLibrary(name, True)
End Using
End Sub
3.編譯解決方案。
4.將命令行變量改變為:Create MyLib
圖例 3
更改命令行變量
5.使用快捷鍵CTRL+F5來運行該應用程序。然後打來Windows Explorer來驗證你所創建的新的庫。
圖例 4
通過Shell API來創建我的第一個庫
任務 3 –添加AddFolder 和RemoveFolder 命令
1.使用一個已經存在的庫,我們需要創建一個ShellLibrary實例來加載這個已經存在的庫。ShellLibrary給我們提供了兩種加載方法:
C#
// Summary:
// Load the library using a number of options
// Parameters:
// sourceKnownFolder: the Knowfolder
// isReadOnly:
// Returns: A ShellLibrary Object
public static ShellLibrary Load(IKnownFolder sourceKnownFolder, bool isReadOnly);
// Summary:
// Load the library using a number of options
// Returns: A ShellLibrary Object
public static ShellLibrary Load(string libraryName, bool isReadOnly);
// Summary:
// Load the library using a number of options
// Returns: A ShellLibrary Object
public static ShellLibrary Load(string libraryName, string folderPath,
bool isReadOnly);
Visual Basic
' Summary:
' Load the library using a number of options
' Parameters:
' sourceKnownFolder: the Knowfolder
' isReadOnly:
' Returns: A ShellLibrary Object
Public Shared Function Load(ByVal sourceKnownFolder As Microsoft.WindowsAPICodePack.Shell.IKnownFolder, ByVal isReadOnly As Boolean) As Microsoft.WindowsAPICodePack.Shell.ShellLibrary
' Summary:
' Load the library using a number of options
' Returns: A ShellLibrary Object
Public Shared Function Load(ByVal libraryName As String, ByVal isReadOnly As Boolean) As Microsoft.WindowsAPICodePack.Shell.ShellLibrary
' Summary:
' Load the library using a number of options
' Returns: A ShellLibrary Object
Public Shared Function Load(ByVal libraryName As String, ByVal folderPath As String, ByVal isReadOnly As Boolean) As Microsoft.WindowsAPICodePack.Shell.ShellLibrary
2.想要添加或者刪除文件夾,我們需要使用下面這些方法中的兩個:
C#
// Summary:
// Add a new FileSystemFolder or SearchConnector
public void Add(FileSystemFolder item);
//
// Summary:
// Add an existing folder to this library
public void Add(string folderPath);
// Summary:
// Remove a folder or search connector
public bool Remove(FileSystemFolder item);
//
// Summary:
// Remove a folder or search connector
public bool Remove(string folderPath);
Visual Basic
' Summary:
' Add a new FileSystemFolder or SearchConnector
Public Sub Add(ByVal item As FileSystemFolder)
'
' Summary:
' Add an existing folder to this library
Public Sub Add(ByVal folderPath As String)
' Summary:
' Remove a folder or search connector
Public Function Remove(ByVal item As FileSystemFolder) As Boolean
'
' Summary:
' Remove a folder or search connector
Public Function Remove(ByVal folderPath As String) As Boolean
3.現在,我們已經知道了如何打開(加載)一個現有的庫,並且如何添加和刪除文件夾,那麼,我們就可以再我們的SLUtil應用程序中來實現AddFolder 和 RemoveFolder命令了。在ShellCommands中,添加如下代碼:
(代碼片段– Shell Libraries – AddAndRemoveFolderCommands CSharp)
C#
[Command(
Name = "AddFolder",
Usage = "SLUtil AddFolder LibraryName FolderPath",
Info = "Add a folder to a library",
Example = @"SLUtil AddFolder Documents C:\Docs")]
public static void AddFolder(string name, string folderPath)
{
using (ShellLibrary library = ShellLibrary.Load(name, false))
{
library.Add(folderPath);
}
}
[Command(
Name = "RemoveFolder",
Usage = "SLUtil RemoveFolder LibraryName FolderPath",
Info = "Remove a folder from a library",
Example = @"SLUtil RemoveFolder Documents C:\Docs")]
public static void RemoveFolder(string name, string folderPath)
{
using (ShellLibrary library = ShellLibrary.Load(name, false))
{
library.Remove(folderPath);
}
}
(代碼片段– Shell Libraries – AddAndRemoveFolderCommands VB)
Visual Basic
<Command(Name:="AddFolder", Usage:="SLUtil AddFolder LibraryName FolderPath", Info:="Add a folder to a library", Example:="SLUtil AddFolder Documents C:\Docs")> _
Public Sub AddFolder(ByVal name As String, ByVal folderPath As String)
Using library = ShellLibrary.Load(name, False)
library.Add(folderPath)
End Using
End Sub
<Command(Name:="RemoveFolder", Usage:="SLUtil RemoveFolder LibraryName FolderPath", Info:="Remove a folder from a library", Example:="SLUtil RemoveFolder Documents C:\Docs")> _
Public Sub RemoveFolder(ByVal name As String, ByVal folderPath As String)
Using library = ShellLibrary.Load(name, False)
library.Remove(folderPath)
End Using
End Sub
4.使用快捷鍵(CTRL+SHIFT+B)生成解決方案,然後按照下面的這些步驟來驗證結果:
a.在項目屬性頁的調試面板中,清空命令行變量。
b.打開一個命令行窗口,並且將目錄(cd)改變到SLUtil.exe文件的所在位置(…\debug\SLUtil.exe)
c.打開緊鄰命令行窗口的庫Shell文件夾,你將會看到你使用SLUtil工具所做的變化。
圖例 5
設置執行SLUtil.exe的環境
d.在命令行中執行SLUtil:
Command Line
SLUtil ?
SLUtil Create NewLibrary
SLUtil AddFolder NewLibrary C:\Users
SLUtil RemoveFolder NewLibrary C:\Users
注意:由於解釋器能夠找到最為匹配的命令,所以你可以使用“SLUtil Cr Lib”這種指令去創建一個庫,或者使用“SLUtil Add Lib C:\”指令去添加一個文件夾。嘗試一下。
任務 4 –添加Delete 和 Rename 命令
刪除一個庫,不是一個IshellLibrary操作;它僅僅是一個普通的文件系統操作。但是,為了完全的完成預期功能,我們也將實現它。而重命名操作,我們可以通過將原有的庫拷貝到新的位置,然後刪除原有的庫來實現重命名。ShellLibrary提供了這些方法:
C#
// Summary:
// Creates a copy of a ShellLibrary, using a new name and known folder
public static ShellLibrary Copy(ShellLibrary library, string name,
IKnownFolder destinationKnownFolder, bool overrideExisting);
// Summary:
// Creates a copy of a ShellLibrary, using a new name and path
public static ShellLibrary Copy(ShellLibrary library, string name,
string path, bool overrideExisting);
Visual Basic
' Summary:
' Creates a copy of a ShellLibrary, using a new name and known folder
Public Shared Function Copy(ByVal library As ShellLibrary, ByVal name As String, ByVal destinationKnownFolder As IKnownFolder, ByVal overrideExisting As Boolean) As ShellLibrary
' Summary:
' Creates a copy of a ShellLibrary, using a new name and path
Public Shared Function Copy(ByVal library As ShellLibrary, ByVal name As String, ByVal path As String, ByVal overrideExisting As Boolean) As ShellLibrary
1.在ShellCommands.cs (C#) 或者 ShellCommands.vb (Visual Basic)文件中直接添加下面的命名空間的引用。
C#
using System.IO;
Visual Basic
Imports System.IO
2.在ShellCommands中添加如下代碼:
(代碼片段– Shell Libraries – DeleteAndRenameLibraryCommands CSharp)
C#
[Command(
Name = "Delete",
Usage = "SLUtil Delete LibraryName",
Info = "Delete a library",
Example = "SLUtil Delete MyLib")]
public static void DeleteLibrary(string name)
{
string librariesPath = Path.Combine(
Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData),
ShellLibrary.LibrariesKnownFolder.RelativePath);
string libraryPath = Path.Combine(librariesPath, name);
string libraryFullPath = Path.ChangeExtension(libraryPath, "library-ms");
File.Delete(libraryFullPath);
}
[Command(
Name = "Rename",
Usage = "SLUtil Rename OldName NewName",
Info = "Rename a library",
Example = "SLUtil Rename MyLib MyLibNewName")]
public static void RenameLibrary(string oldName, string newName)
{
using (ShellLibrary library = ShellLibrary.Load(oldName, true))
{
ShellLibrary.Copy(library, newName, ShellLibrary.LibrariesKnownFolder, false);
}
DeleteLibrary(oldName);
}
(代碼片段– Shell Libraries – DeleteAndRenameLibraryCommands VB)
Visual Basic
<Command(Name:="Delete", Usage:="SLUtil Delete LibraryName", Info:="Delete a library", Example:="SLUtil Delete MyLib")> _
Public Sub DeleteLibrary(ByVal name As String)
Dim librariesPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ShellLibrary.LibrariesKnownFolder.RelativePath)
Dim libraryPath = Path.Combine(librariesPath, name)
Dim libraryFullPath = Path.ChangeExtension(libraryPath, "library-ms")
File.Delete(libraryFullPath)
End Sub
<Command(Name:="Rename", Usage:="SLUtil Rename OldName NewName", Info:="Rename a library", Example:="SLUtil Rename MyLib MyLibNewName")> _
Public Sub RenameLibrary(ByVal oldName As String, ByVal newName As String)
Using library = ShellLibrary.Load(oldName, True)
ShellLibrary.Copy(library, newName, ShellLibrary.LibrariesKnownFolder, False)
End Using
DeleteLibrary(oldName)
End Sub
3.使用快捷鍵(CTRL+SHIFT+B)生成解決方案,並且根據下面的步驟來驗證結果:
a.打開一個命令行窗口,並且將目錄(cd)切換到SLUtil.exe所在的位置。
b.打開緊鄰命令行窗口的庫Shell文件夾,你將會看到你使用SLUtil工具所做的變化。
c.在命令行中測試SLUtil:
Command Line
SLUtil.exe Rename MyLib MyLib2