本主题介绍如何创建可导航数据存储的 Windows PowerShell 导航提供程序。 这种类型的提供程序支持递归命令、嵌套容器和相对路径。
注释
可以使用适用于 Windows Vista 和 .NET Framework 3.0 运行时组件的 Microsoft Windows 软件开发工具包下载此提供程序的 C# 源文件(AccessDBSampleProvider05.cs)。 有关下载说明,请参阅 如何安装 Windows PowerShell 并下载 Windows PowerShell SDK。 <PowerShell 示例> 目录中提供了下载的源文件。 有关其他 Windows PowerShell 提供程序实现的详细信息,请参阅 设计 Windows PowerShell 提供程序。
此处所述的提供程序使用户能够将 Access 数据库作为驱动器进行处理,以便用户可以导航到数据库中的数据表。 创建自己的导航提供程序时,可以实施方法,使导航所需的驱动器限定路径、规范化相对路径、移动数据存储的项以及获取子名称的方法、获取项的父路径,并测试以确定项是否为容器。
谨慎
请注意,此设计假定数据库具有具有名称 ID 的字段,并且该字段的类型为 LongInteger。
定义 Windows PowerShell 提供程序
Windows PowerShell 导航提供程序必须创建派生自 System.Management.Automation.Provider.NavigationCmdletProvider 基类的 .NET 类。 下面是本部分所述的导航提供程序的类定义。
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : NavigationCmdletProvider
请注意,在此提供程序中,System.Management.Automation.Provider.CmdletProviderAttribute 属性包含两个参数。 第一个参数指定 Windows PowerShell 使用的提供程序的用户友好名称。 第二个参数指定提供程序在命令处理期间向 Windows PowerShell 运行时公开的 Windows PowerShell 特定功能。 对于此提供程序,没有添加 Windows PowerShell 特定功能。
定义基本功能
如 设计 PS 提供程序中所述,System.Management.Automation.Provider.NavigationCmdletProvider 基类派生自提供不同提供程序功能的几个其他类。 因此,Windows PowerShell 导航提供程序必须定义这些类提供的所有功能。
若要实现用于添加特定于会话的初始化信息和释放提供程序使用的资源的功能,请参阅 创建基本 PS 提供程序。 但是,大多数提供程序(包括此处所述的提供程序)都可以使用 Windows PowerShell 提供此功能的默认实现。
若要通过 Windows PowerShell 驱动器访问数据存储,必须实现 System.Management.Automation.Provider.DriveCmdletProvider 基类的方法。 有关实现这些方法的详细信息,请参阅 创建 Windows PowerShell 驱动器提供程序。
若要作数据存储的项(如获取、设置和清除项),提供程序必须实现由 System.Management.Automation.Provider.ItemCmdletProvider 基类提供的方法。 有关实现这些方法的详细信息,请参阅 创建 Windows PowerShell 项提供程序。
若要访问数据存储的子项或其名称,以及创建、复制、重命名和删除项的方法,必须实现 System.Management.Automation.Provider.ContainerCmdletProvider 基类提供的方法。 有关实现这些方法的详细信息,请参阅 创建 Windows PowerShell 容器提供程序。
创建 Windows PowerShell 路径
Windows PowerShell 导航提供程序使用提供程序内部的 Windows PowerShell 路径来导航数据存储的项。 若要创建提供程序内部路径,提供程序必须实现 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 方法,以便支持来自 Combine-Path cmdlet 的调用。 此方法使用父路径和子路径之间的提供程序特定的路径分隔符将父路径和子路径合并到提供程序内部路径中。
默认实现采用路径“/”或“\”作为路径分隔符,将路径分隔符规范化为“\”,将父路径和子路径部分与它们之间的分隔符合并,然后返回包含组合路径的字符串。
此导航提供程序不实现此方法。 但是,以下代码是 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 方法的默认实现。
有关实现 MakePath 的注意事项
以下条件适用于 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath*的实现:
System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 方法的实现不应验证路径作为提供程序命名空间中合法完全限定的路径。 请注意,每个参数只能表示路径的一部分,并且组合部分可能不会生成完全限定的路径。 例如,FileSystem 提供程序的 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 方法可能会在
parent
参数中接收“windows\system32”,child
参数中的“abc.dll”。 该方法将这些值与“\”分隔符联接,并返回“windows\system32\abc.dll”,这不是完全限定的文件系统路径。重要
调用中提供的路径部件 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 可能包含提供程序命名空间中不允许的字符。 这些字符最有可能用于通配符扩展,此方法的实现不应删除它们。
检索父路径
Windows PowerShell 导航提供程序实现 System.Management.Automation.Provider.NavigationCmdletProvider.GetParentPath* 方法,以检索指示的完整或部分提供程序特定路径的父部分。 该方法删除路径的子部分并返回父路径部分。
root
参数指定驱动器根目录的完全限定路径。 如果装载的驱动器未用于检索作,则此参数可以为 null 或为空。 如果指定了根,该方法必须返回与根树相同的容器的路径。
示例导航提供程序不会重写此方法,而是使用默认实现。 它接受将“/”和“\”用作路径分隔符的路径。 它首先将路径规范化为只有“\”分隔符,然后将父路径拆分为最后一个“\”,并返回父路径。
记住如何实现 GetParentPath
System.Management.Automation.Provider.NavigationCmdletProvider.GetParentPath* 方法的实现应在提供程序命名空间的路径分隔符上按词法拆分路径。 例如,FileSystem 提供程序使用此方法查找最后一个“\”,并将所有内容返回到分隔符左侧。
检索子路径名称
导航提供程序实现 System.Management.Automation.Provider.NavigationCmdletProvider.GetChildName* 方法,以检索位于指示的完整或部分提供程序特定路径的项的子项的名称(叶元素)。
示例导航提供程序不会重写此方法。 默认实现如下所示。 它接受将“/”和“\”用作路径分隔符的路径。 它首先将路径规范化为只有“\”分隔符,然后将父路径拆分为最后一个“\”,并返回子路径部分的名称。
有关实现 GetChildName 的注意事项
System.Management.Automation.Provider.NavigationCmdletProvider.GetChildName* 方法的实现应在路径分隔符上按词法拆分路径。 如果提供的路径不包含路径分隔符,则该方法应返回未修改的路径。
重要
调用此方法中提供的路径可能包含提供程序命名空间中非法的字符。 这些字符最有可能用于通配符扩展或正则表达式匹配,并且此方法的实现不应删除它们。
确定项是否为容器
导航提供程序可以实现 System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* 方法,以确定指定的路径是否指示容器。 如果路径表示容器,则返回 true;否则返回 false。 用户需要此方法才能将 Test-Path
cmdlet 用于提供的路径。
以下代码显示了示例导航提供程序中的 System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* 实现。 该方法验证指定的路径是否正确以及表是否存在,如果路径指示容器,则返回 true。
protected override bool IsItemContainer(string path)
{
if (PathIsDrive(path))
{
return true;
}
string[] pathChunks = ChunkPath(path);
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Table)
{
foreach (DatabaseTableInfo ti in GetTables())
{
if (string.Equals(ti.Name, tableName, StringComparison.OrdinalIgnoreCase))
{
return true;
}
} // foreach (DatabaseTableInfo...
} // if (pathChunks...
return false;
} // IsItemContainer
有关实现 IsItemContainer 的注意事项
导航提供程序 .NET 类可能会从 System.Management.Automation.Provider.ProviderCapabilities 枚举中声明 ExpandWildcards、Filter、Include 或 Exclude 的提供程序功能。 在这种情况下,System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* 的实现 需要确保通过的路径满足要求。 为此,该方法应访问相应的属性,例如,System.Management.Automation.Provider.CmdletProvider.Exclude* 属性。
移动项
为了支持 Move-Item
cmdlet,导航提供程序实现 System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* 方法。 此方法将 path
参数指定的项移动到 destination
参数中提供的路径上的容器。
示例导航提供程序不会替代 System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* 方法。 下面是默认实现。
有关实现 MoveItem 的注意事项
导航提供程序 .NET 类可能会从 System.Management.Automation.Provider.ProviderCapabilities 枚举中声明 ExpandWildcards、Filter、Include 或 Exclude 的提供程序功能。 在这种情况下,System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* 的实现必须确保通过的路径满足要求。 为此,该方法应访问相应的属性,例如,CmdletProvider.Exclude 属性。
默认情况下,除非 System.Management.Automation.Provider.CmdletProvider.Force* 属性设置为 true
,否则此方法的重写不应将对象移到现有对象上。 例如,FileSystem 提供程序不会通过现有 C:\bar.txt 文件复制 C:\temp\abc.txt,除非 System.Management.Automation.Provider.CmdletProvider.Force* 属性设置为 true
。 如果 destination
参数中指定的路径存在并且是容器,则不需要 System.Management.Automation.Provider.CmdletProvider.Force* 属性。 在这种情况下,System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* 应将 path
参数指示的项移动到由 destination
参数指示的容器作为子级。
System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* 方法的实现应调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess,并在对数据存储进行任何更改之前检查其返回值。 此方法用于在对系统状态进行更改时确认作的执行,例如删除文件。 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 将要更改的资源的名称发送给用户,Windows PowerShell 运行时考虑到了任何命令行设置或首选项变量,以确定应向用户显示的内容。
调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 返回 true
后,System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* 方法应调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法。 此方法向用户发送一条消息,以允许反馈说明是否应继续作。 提供程序应调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 作为对潜在危险系统修改的附加检查。
将动态参数附加到 Move-Item Cmdlet
有时,Move-Item
cmdlet 需要在运行时动态提供的其他参数。 若要提供这些动态参数,导航提供程序必须实现 System.Management.Automation.Provider.NavigationCmdletProvider.MoveItemDynamicParameters* 方法,以便从指示路径的项获取所需的参数值,并返回具有与 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象类似的属性和字段的对象。
此导航提供程序不实现此方法。 但是,以下代码是 System.Management.Automation.Provider.NavigationCmdletProvider.MoveItemDynamicParameters*的默认实现。
规范化相对路径
导航提供程序实现 System.Management.Automation.Provider.NavigationCmdletProvider.NormalizeRelativePath* 方法,以规范化 path
参数中指示的完全限定路径,作为相对于 basePath
参数指定的路径。 该方法返回规范化路径的字符串表示形式。 如果 path
参数指定不存在的路径,它将写入错误。
示例导航提供程序不会重写此方法。 下面是默认实现。
有关实现 NormalizeRelativePath 的注意事项
System.Management.Automation.Provider.NavigationCmdletProvider.NormalizeRelativePath* 的实现应分析 path
参数,但它不必使用纯语法分析。 建议你设计此方法以使用路径来查找数据存储中的路径信息,并创建与大小写和标准化路径语法匹配的路径。
代码示例
有关完整的示例代码,请参阅 AccessDbProviderSample05 代码示例。
定义对象类型和格式
提供程序可以将成员添加到现有对象或定义新对象。 有关详细信息,请参阅扩展对象类型和格式。
生成 Windows PowerShell 提供程序
有关详细信息,请参阅 如何注册 Cmdlet、提供程序和主机应用程序。
测试 Windows PowerShell 提供程序
向 Windows PowerShell 注册 Windows PowerShell 提供程序后,可以通过在命令行上运行支持的 cmdlet 来测试它,包括派生提供的 cmdlet。 此示例将测试示例导航提供程序。
运行新 shell 并使用
Set-Location
cmdlet 设置路径以指示 Access 数据库。Set-Location mydb:
现在,运行
Get-ChildItem
cmdlet 以检索数据库项的列表,这些数据库项是可用的数据库表。 对于每个表,此 cmdlet 还会检索表行数。Get-ChildItem | Format-Table RowCount, Name -AutoSize
RowCount Name -------- ---- 180 MSysAccessObjects 0 MSysACEs 1 MSysCmdbars 0 MSysIMEXColumns 0 MSysIMEXSpecs 0 MSysObjects 0 MSysQueries 7 MSysRelationships 8 Categories 91 Customers 9 Employees 2155 Order Details 830 Orders 77 Products 3 Shippers 29 Suppliers
再次使用
Set-Location
cmdlet 设置 Employees 数据表的位置。Set-Location Employees
现在,让我们使用
Get-Location
cmdlet 检索 Employees 表的路径。Get-Location
Path ---- mydb:\Employees
现在使用通过管道传递给
Format-Table
cmdlet 的Get-ChildItem
cmdlet。 此 cmdlet 集检索 Employees 数据表(即表行)的项。 它们的格式由Format-Table
cmdlet 指定。Get-ChildItem | Format-Table RowNumber, PSIsContainer, Data -AutoSize
RowNumber PSIsContainer Data --------- -------------- ---- 0 False System.Data.DataRow 1 False System.Data.DataRow 2 False System.Data.DataRow 3 False System.Data.DataRow 4 False System.Data.DataRow 5 False System.Data.DataRow 6 False System.Data.DataRow 7 False System.Data.DataRow 8 False System.Data.DataRow
现在可以运行
Get-Item
cmdlet 来检索 Employees 数据表第 0 行的项。Get-Item 0
PSPath : AccessDB::C:\PS\Northwind.mdb\Employees\0 PSParentPath : AccessDB::C:\PS\Northwind.mdb\Employees PSChildName : 0 PSDrive : mydb PSProvider : System.Management.Automation.ProviderInfo PSIsContainer : False Data : System.Data.DataRow RowNumber : 0
再次使用
Get-Item
cmdlet 检索第 0 行中项的员工数据。(Get-Item 0).Data
EmployeeID : 1 LastName : Davis FirstName : Sara Title : Sales Representative TitleOfCourtesy : Ms. BirthDate : 12/8/1968 12:00:00 AM HireDate : 5/1/1992 12:00:00 AM Address : 4567 Main Street Apt. 2A City : Buffalo Region : NY PostalCode : 98052 Country : USA HomePhone : (206) 555-9857 Extension : 5467 Photo : EmpID1.bmp Notes : Education includes a BA in psychology from Colorado State University. She also completed "The Art of the Cold Call." Nancy is a member of Toastmasters International. ReportsTo : 2