本主题描述如何创建一个可以作数据存储中数据的 Windows PowerShell 提供者。 在本主题中,存储中的数据元素被称为数据存储的“项目”。 因此,能够作存储中数据的提供者被称为 Windows PowerShell 项目提供者。
注释
您可以使用 Microsoft Windows Vista 软件开发工具包和 .NET Framework 3.0 运行时组件下载该提供者的 C# 源文件(AccessDBSampleProvider03.cs)。 有关下载说明,请参见 《如何安装Windows PowerShell》和《Windows PowerShell SDK》。
下载的源文件可在 PowerShell Samples 目录中获取。 有关其他 Windows PowerShell 提供者实现的更多信息,请参见 “设计你的 Windows PowerShell 提供者”。
本主题中描述的 Windows PowerShell 项提供者从访问数据库获取数据项。 在这种情况下,“项目”要么是 Access 数据库中的一个表,要么是表中的一个行。
定义 Windows PowerShell item provider 类
Windows PowerShell 项目提供者必须定义一个从 System.Management.Automation.Provider.ItemCmdletProvider 基类派生的 .NET 类。 以下是本节中描述的项目提供者的类定义。
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ItemCmdletProvider
注意,在本类定义中, System.Management.Automation.Provider.CmdletProviderAttribute 属性包含两个参数。 第一个参数指定了 Windows PowerShell 所用提供者的用户友好名称。 第二个参数指定了 Windows PowerShell 在命令处理过程中向 Windows PowerShell 运行时暴露的具体功能。 对于该提供者,没有额外的 Windows PowerShell 特定功能。
定义基础功能
如《 设计你的 Windows PowerShell 提供者》中所述, System.Management.Automation.Provider.DriveCmdletProvider 类源自其他提供不同提供者功能的类。 因此,Windows PowerShell 项目提供者必须定义这些类提供的所有功能。
关于如何实现添加会话特定初始化信息和释放提供者所用资源的功能,请参见 “创建基础 Windows PowerShell 提供者”。 然而,大多数提供者,包括这里描述的提供者,都可以使用 Windows PowerShell 提供的默认实现。
在 Windows PowerShell 项目提供者能够作存储中的项目之前,它必须实现 System.Management.Automation.Provider.DriveCmdletProvider 基类的方法以访问数据存储。 关于实现该类的更多信息,请参见 创建 Windows PowerShell 驱动器提供者。
检测路径有效性
在查找数据项时,Windows PowerShell 运行时会向提供者提供一条 Windows PowerShell 路径,具体定义见《 Windows PowerShell 工作原理》中的“PSPath 概念”部分。 Windows PowerShell 项目提供者必须通过实现 System.Management.Automation.Provider.ItemCmdletProvider.IsValidPath 方法来验证传递给它的路径的语法和语义有效性。 该方法返回路径有效时false返回,否则返回true。 请注意,该方法的实现不应验证路径上项的存在,而仅确认路径在语法和语义上正确。
这是该提供者系统管理自动化服务提供者. ItemCmdletProvider.IsValidPath 方法的实现。 注意,该实现调用了 NormalizePath 辅助方法,将路径中的所有分隔符转换为统一分隔符。
protected override bool IsValidPath(string path)
{
bool result = true;
// check if the path is null or empty
if (String.IsNullOrEmpty(path))
{
result = false;
}
// convert all separators in the path to a uniform one
path = NormalizePath(path);
// split the path into individual chunks
string[] pathChunks = path.Split(pathSeparator.ToCharArray());
foreach (string pathChunk in pathChunks)
{
if (pathChunk.Length == 0)
{
result = false;
}
}
return result;
} // IsValidPath
确定某个物品是否存在
验证路径后,Windows PowerShell运行时必须判断该路径是否存在数据项。 为了支持这种类型的查询,Windows PowerShell 项目提供者实现了 System.Management.Automation.Provider.ItemCmdletProvider.ItemExists 方法。 该方法返回指定路径上的项目,false否则(默认)返回true。
这是该提供者系统 管理自动化提供者.ItemCmdletProvider.ItemExists 方法的实现。 注意,该方法调用 了 PathIsDrive、 ChunkPath 和 GetTable 辅助方法,并使用提供者定义的 DatabaseTableInfo 对象。
protected override bool ItemExists(string path)
{
// check if the path represented is a drive
if (PathIsDrive(path))
{
return true;
}
// Obtain type, table name and row number from path
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
DatabaseTableInfo table = GetTable(tableName);
if (type == PathType.Table)
{
// if specified path represents a table then DatabaseTableInfo
// object for the same should exist
if (table != null)
{
return true;
}
}
else if (type == PathType.Row)
{
// if specified path represents a row then DatabaseTableInfo should
// exist for the table and then specified row number must be within
// the maximum row count in the table
if (table != null && rowNumber < table.RowCount)
{
return true;
}
}
return false;
} // ItemExists
实现ItemExists时需要记住的事项
以下条件可能适用于您的 System.Management.Automation.Provider.ItemCmdletProvider.ItemExists的实现:
- 在定义提供者类时,Windows PowerShell 项目提供者可能会声明
ExpandWildcards,Filter,Include, 或Exclude,来自 System.Management.Automation.Provider.ProviderCapabilities 枚举。 在这些情况下, System.Management.Automation.Provider.ItemCmdletProvider.ItemExists 方法的实现必须确保传递给该方法的路径满足指定能力的要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 和 System.Management.Automation.Provider.CmdletProvider.Include 属性。 - 该方法的实现应处理任何可能让用户可见的访问方式。 例如,如果用户通过 FileSystem 提供者(由 Windows PowerShell 提供)对文件有写权限,但没有读取权限,文件仍然存在, System.Management.Automation.Provider.ItemCmdletProvider.ItemExists 返回
true。 你的实现可能需要检查父项,看看子项是否可以枚举。
将动态参数附加到 Test-Path cmdlet
有时调用System.Management.Automation.Provider.ItemCmdletProvider.ItemExists的Test-Path命令包需要在运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 项目提供者必须实现 System.Management.Automation.Provider.ItemCmdletProvider.ItemExistsDynamicParameters 方法。 该方法检索指定路径上项目的动态参数,返回一个具有类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象的属性和字段的对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Test-Path cmdlet。
这个 Windows PowerShell 项目提供者并未实现该方法。 不过,以下代码是该方法的默认实现。
检索物品
要检索项目,Windows PowerShell 项目提供者必须覆盖 System.Management.Automation.Provider.ItemCmdletProvider.GetItem 方法,以支持从 cmdlet 调用 Get-Item 。 该方法使用 System.Management.Automation.Provider.CmdletProvider.WriteItemObject 方法写入该项目。
这是该提供者系统管理自动化服务提供者( System.Management.Automation.Provider.ItemCmdletProvider.GetItem )方法的实现。 注意,该方法使用 GetTable 和 GetRow 辅助方法来检索Access数据库中的表或数据表中的行项。
protected override void GetItem(string path)
{
// check if the path represented is a drive
if (PathIsDrive(path))
{
WriteItemObject(this.PSDriveInfo, path, true);
return;
}// if (PathIsDrive...
// Get table name and row information from the path and do
// necessary actions
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Table)
{
DatabaseTableInfo table = GetTable(tableName);
WriteItemObject(table, path, true);
}
else if (type == PathType.Row)
{
DatabaseRowInfo row = GetRow(tableName, rowNumber);
WriteItemObject(row, path, false);
}
else
{
ThrowTerminatingInvalidPathException(path);
}
} // GetItem
关于实现GetItem需要注意的事项
以下条件可能适用于 System.Management.Automation.Provider.ItemCmdletProvider.GetItem的实现:
在定义提供者类时,Windows PowerShell 项目提供者可能会声明
ExpandWildcards,Filter,Include, 或Exclude,来自 System.Management.Automation.Provider.ProviderCapabilities 枚举。 在这种情况下, System.Management.Automation.Provider.ItemCmdletProvider.GetItem 的实现必须确保传递给方法的路径满足这些要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 和 System.Management.Automation.Provider.CmdletProvider.Include 属性。默认情况下,该方法的覆盖不应检索通常对用户隐藏的对象,除非将 System.Management.Automation.Provider.CmdletProvider.Force 属性设置为
true。 例如,SystemSystem提供者中的System.Management.Automation.Provider.ItemCmdletProvider.GetItem方法,在尝试调用System.Management.Automation.Provider.CmdletProvider.WriteItemObject查找隐藏文件或系统文件之前,会检查System.Management.Automation.Provider.CmdletProvider.WriteItemObject属性。
将动态参数附加到 Get-Item cmdlet
有时 Get-Item cmdlet 需要在运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 项目提供者必须实现 System.Management.Automation.Provider.ItemCmdletProvider.GetItemDynamicParameters 方法。 该方法检索指定路径上项目的动态参数,返回一个具有类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象的属性和字段的对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Get-Item cmdlet。
该提供者未实现该方法。 不过,以下代码是该方法的默认实现。
设置物品
要设置一个项,Windows PowerShell 项提供者必须覆盖 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法,以支持该 Set-Item 命令调用。 该方法设定指定路径处的项值。
该提供者不提供 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法的覆盖。 不过,以下是该方法的默认实现。
实现 SetItem 需要注意的事项
以下条件可能适用于您对 System.Management.Automation.Provider.ItemCmdletProvider.SetItem的实现:
在定义提供者类时,Windows PowerShell 项目提供者可能会声明
ExpandWildcards,Filter,Include, 或Exclude,来自 System.Management.Automation.Provider.ProviderCapabilities 枚举。 在这些情况下, System.Management.Automation.Provider.ItemCmdletProvider.SetItem 的实现必须确保传递给方法的路径满足这些要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 和 System.Management.Automation.Provider.CmdletProvider.Include 属性。默认情况下,除非将 System.Management.Automation.Provider.CmdletProvider.Force 属性设置为
true。 如果路径代表隐藏项且 System.Management.Automation.Provider.CmdletProvider.Force 设置为false。你实现 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法,应在对数据存储进行任何更改前调用 System.Management.Automation.Provider.CommandletProvider.ShouldProcess 并验证其返回值。 该方法用于在数据存储发生更改时确认作的执行,例如删除文件。 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 方法会将待更改资源的名称发送给用户,Windows PowerShell 运行时会考虑命令行设置或偏好变量来决定应显示的内容。
在调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 返回
true后, System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法应调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法。 该方法向用户发送消息,允许反馈以验证作是否应继续。 调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 可以额外检查潜在危险的系统修改。
获取 SetItem 的动态参数
有时 Set-Item cmdlet 需要在运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 项目提供者必须实现 System.Management.Automation.Provider.ItemCmdletProvider.SetItemDynamicParameters 方法。 该方法检索指定路径上项目的动态参数,返回一个具有类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象的属性和字段的对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Set-Item cmdlet。
该提供者未实现该方法。 不过,以下代码是该方法的默认实现。
清除一个项目
为了清除一个项目,Windows PowerShell 项目提供者实现了 System.Management.Automation.Provider.ItemCmdletProvider.ClearItem 方法,以支持从 Clear-Item 该命令调用。 该方法在指定路径处擦除数据项。
该提供者未实现该方法。 不过,以下代码是该方法的默认实现。
实现ClearItem需要注意的事项
以下条件可能适用于 System.Management.Automation.Provider.ItemCmdletProvider.ClearItem的实现:
在定义提供者类时,Windows PowerShell 项目提供者可能会声明
ExpandWildcards,Filter,Include, 或Exclude,来自 System.Management.Automation.Provider.ProviderCapabilities 枚举。 在这种情况下, System.Management.Automation.Provider.ItemCmdletProvider.ClearItem 的实现必须确保传递给方法的路径满足这些要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 和 System.Management.Automation.Provider.CmdletProvider.Include 属性。默认情况下,除非将 System.Management.Automation.Provider.CmdletProvider.Force 属性设置为
true。 如果路径代表对用户隐藏的项目,且 System.Management.Automation.Provider.CmdletProvider.Force 设置为false,则应向 System.Management.Automation.Provider.CmdletProvider.Write Error 方法发送错误。你实现 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法,应在对数据存储进行任何更改前调用 System.Management.Automation.Provider.CommandletProvider.ShouldProcess 并验证其返回值。 该方法用于在数据存储发生更改时确认作的执行,例如删除文件。 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 方法通过 Windows PowerShell 运行时向用户发送待更改资源的名称,并处理命令行设置或偏好变量,决定应显示哪些内容。
在调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 返回
true后, System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法应调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法。 该方法向用户发送消息,允许反馈以验证作是否应继续。 调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 可以额外检查潜在危险的系统修改。
检索 ClearItem 的动态参数
有时 Clear-Item cmdlet 需要在运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 项目提供者必须实现 System.Management.Automation.Provider.ItemCmdletProvider.ClearItemDynamicParameters 方法。 该方法检索指定路径上项目的动态参数,返回一个具有类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象的属性和字段的对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Clear-Item cmdlet。
该项目提供者不实现该方法。 不过,以下代码是该方法的默认实现。
执行一项物品的默认动作
Windows PowerShell 项目提供者可以实现 System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction 方法,以支持从 cmdlet 调用 Invoke-Item ,使提供者能够在指定路径上对该项目执行默认作。 例如,FileSystem提供者可能会使用此方法调用特定项目的 ShellExecute 。
该提供者未实现该方法。 不过,以下代码是该方法的默认实现。
关于实现InvokeDefaultAction需要注意的事项
以下条件可能适用于 System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction的实现:
在定义提供者类时,Windows PowerShell 项目提供者可能会声明
ExpandWildcards,Filter,Include, 或Exclude,来自 System.Management.Automation.Provider.ProviderCapabilities 枚举。 在这种情况下, System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction 的实现必须确保传递给方法的路径满足这些要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 和 System.Management.Automation.Provider.CmdletProvider.Include 属性。默认情况下,除非将 System.Management.Automation.Provider.CmdletProvider.Force 属性设置为
true,否则该方法的覆盖不应设置或写入对用户隐藏的对象。 如果路径代表对用户隐藏的项目,且 System.Management.Automation.Provider.CmdletProvider.Force 设置为false,则应向 System.Management.Automation.Provider.CmdletProvider.Write Error 方法发送错误。
检索 InvokeDefaultAction 的动态参数
有时 Invoke-Item cmdlet 需要在运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 项目提供者必须实现 System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultActionDynamicParameters 方法。 该方法检索指定路径上项目的动态参数,返回一个具有类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象的属性和字段的对象。 Windows PowerShell运行时使用返回的对象向cmdlet添加动态参数 Invoke-Item 。
该项目提供者不实现该方法。 不过,以下代码是该方法的默认实现。
实现辅助方法和类
该项提供者实现了多个辅助方法和类,这些方法被 Windows PowerShell 定义的公共覆盖方法所使用。 这些辅助方法和类的代码见 代码 示例部分。
NormalizePath 方法
该项目提供者实现了 NormalizePath 辅助方法,以确保路径格式一致。 所规定的格式使用反斜杠(\)作为分隔符。
PathIsDrive 方法
该项目提供者实现了 PathIsDrive 辅助方法,用于判断指定的路径是否真的是驱动器名称。
块路径方法
该项目提供者实现了 ChunkPath 辅助方法,将指定路径拆分,使提供者能够识别其各个元素。 它返回由路径元素组成的数组。
GetTable方法
该项提供者实现了 GetTables 辅助方法,返回一个 DatabaseTableInfo 对象,表示调用中指定的表信息。
GetRow 方法
该项目提供者的 System.Management.Automation.Provider.ItemCmdletProvider.GetItem 方法调用 GetRows 助手方法。 该辅助方法检索一个 DatabaseRowInfo 对象,表示表中指定行的信息。
DatabaseTableInfo 类
该项提供者定义了一个 DatabaseTableInfo 类,表示数据库中数据表中的一组信息。 该类类似于 System.IO.Directoryinfo 类。
示例项提供者定义了一个 DatabaseTableInfo.GetTables 方法,返回定义数据库中表的表信息对象集合。 该方法包含尝试/捕捉块,确保任何数据库错误都显示为零条目行。
DatabaseRowInfo 类
该项提供者定义了 DatabaseRowInfo 辅助类,代表数据库表中的一行。 该类类似于 System.IO.FileInfo 类。
示例提供者定义了一个 DatabaseRowInfo.GetRows 方法,用于返回指定表的行信息对象集合。 该方法包含尝试/接球块以捕捉异常。 任何错误都会导致无行信息。
代码示例
完整示例代码请参见 AccessDbProviderSample03 代码示例。
定义对象类型与格式
在编写提供者时,可能需要向现有对象添加成员或定义新对象。 完成后,创建一个 Types 文件,Windows PowerShell 可用来识别对象成员,以及一个定义对象显示方式的 Format 文件。 更多信息请参见 “扩展对象类型与格式”。
构建 Windows PowerShell 提供者
请参阅 如何注册指令、提供者和托管应用程序。
测试Windows PowerShell提供者
当这个 Windows PowerShell 项目提供者注册到 Windows PowerShell 时,你只能测试该提供者的基本功能和驱动器功能。 为了测试对项的作,你还必须实现《 实现容器 Windows PowerShell 提供者》中描述的容器功能。