创建 Windows PowerShell 驱动器提供者

本主题描述如何创建一个 Windows PowerShell 驱动器提供者,通过 Windows PowerShell 驱动器访问数据存储。 这种类型的提供者也被称为Windows PowerShell驱动器提供者。 提供者使用的 Windows PowerShell 驱动器提供了连接数据存储的手段。

这里描述的 Windows PowerShell 驱动器提供商提供了访问 Microsoft Access 数据库的权限。 对于该提供者,Windows PowerShell驱动器代表数据库(可以向驱动器提供者添加任意数量的驱动器),驱动器的顶层容器表示数据库中的表,容器中的项代表表中的行。

定义 Windows PowerShell 提供者类

你的硬盘提供者必须定义一个源自 System.Management.Automation.Provider.DriveCmdletProvider 基类的 .NET 类。 以下是该驱动器提供商的类定义:

[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : DriveCmdletProvider

请注意,在这个例子中, System.Management.Automation.Provider.CmdletProviderAttribute 属性指定了该提供者的用户友好名称,以及提供者在命令处理过程中向 Windows PowerShell 运行时展示的 Windows PowerShell 特定功能。 提供者能力的可能值由 System.Management.Automation.Provider.ProviderCapabilities 枚举定义。 该硬盘供应商不支持上述任何功能。

定义基础功能

如《 设计你的 Windows PowerShell 提供者》中所述, System.Management.Automation.Provider.DriveCmdletProvider 类源自 System.Management.Automation.Provider.CmdletProvider 基类,定义了初始化和取消初始化提供者所需的方法。 要实现添加会话特定初始化信息和释放提供者使用的资源的功能,请参见 创建基础 Windows PowerShell 提供者。 然而,大多数提供者(包括此处描述的提供者)可以使用 Windows PowerShell 提供的该功能的默认实现。

创建驱动器状态信息

所有 Windows PowerShell 提供者都被视为无状态,这意味着你的硬盘提供者需要创建 Windows PowerShell 运行时调用提供者所需的状态信息。

对于该驱动器提供者,状态信息包括作为驱动器信息一部分保存的数据库连接。 这里有一段代码,展示了这些信息如何存储在描述硬盘的 System.Management.Automation.PSDriveinfo 对象中:

internal class AccessDBPSDriveInfo : PSDriveInfo
{
    private OdbcConnection connection;

    /// <summary>
    /// ODBC connection information.
    /// </summary>
    public OdbcConnection Connection
    {
        get { return connection; }
        set { connection = value; }
    }

    /// <summary>
    /// Constructor that takes one argument
    /// </summary>
    /// <param name="driveInfo">Drive provided by this provider</param>
    public AccessDBPSDriveInfo(PSDriveInfo driveInfo)
        : base(driveInfo)
    { }

} // class AccessDBPSDriveInfo

创建硬盘

为了让 Windows PowerShell 运行时创建驱动器,驱动器提供者必须实现 System.Management.Automation.Provider.DriveCmdletProvider.NewDrive* 方法。 以下代码展示了该驱动器提供者 System.Management.Automation.Provider.DriveCmdletProvider.NewDrive* 方法的实现:

      protected override PSDriveInfo NewDrive(PSDriveInfo drive)
      {
          // check if drive object is null
          if (drive == null)
          {
              WriteError(new ErrorRecord(
                  new ArgumentNullException("drive"), 
                  "NullDrive",
                  ErrorCategory.InvalidArgument, 
                  null)
              );
           
              return null;
          }
       
          // check if drive root is not null or empty
          // and if its an existing file
          if (String.IsNullOrEmpty(drive.Root) || (File.Exists(drive.Root) == false))
          {
              WriteError(new ErrorRecord(
                  new ArgumentException("drive.Root"), 
                  "NoRoot",
                  ErrorCategory.InvalidArgument, 
                  drive)
              );

              return null;
          }

          // create a new drive and create an ODBC connection to the new drive
          AccessDBPSDriveInfo accessDBPSDriveInfo = new AccessDBPSDriveInfo(drive);

          OdbcConnectionStringBuilder builder = new OdbcConnectionStringBuilder();

          builder.Driver = "Microsoft Access Driver (*.mdb)";
          builder.Add("DBQ", drive.Root);
         
          OdbcConnection conn = new OdbcConnection(builder.ConnectionString);
          conn.Open();
          accessDBPSDriveInfo.Connection = conn;

          return accessDBPSDriveInfo;
      } // NewDrive

你对此方法的覆盖应实现以下作:

将动态参数附加到NewDrive上

你的硬盘提供商支持的 New-PSDrive cmdlet 可能需要额外的参数。 为了将这些动态参数附加到命令包上,提供者实现了 System.Management.Automation.Provider.DriveCmdletProvider.NewDriveDynamicParameters* 方法。 该方法返回一个具有属性和字段的对象,解析属性类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象。

该驱动器提供商不会覆盖该方法。 然而,以下代码显示了该方法的默认实现:

移除硬盘

要关闭数据库连接,驱动器提供者必须实现 System.Management.Automation.Provider.DriveCmdletProvider.RemoveDrive* 方法。 这种方法在清理所有供应商特定信息后,会关闭与硬盘的连接。

以下代码展示了该驱动器提供者 System.Management.Automation.Provider.DriveCmdletProvider.RemoveDrive* 方法的实现:

protected override PSDriveInfo RemoveDrive(PSDriveInfo drive)
{
    // check if drive object is null
    if (drive == null)
    {
        WriteError(new ErrorRecord(
            new ArgumentNullException("drive"), 
            "NullDrive",
            ErrorCategory.InvalidArgument, 
            drive)
        );

       return null;
    }

    // close ODBC connection to the drive
    AccessDBPSDriveInfo accessDBPSDriveInfo = drive as AccessDBPSDriveInfo;

    if (accessDBPSDriveInfo == null)
    {
        return null;
    }
    accessDBPSDriveInfo.Connection.Close();
  
    return accessDBPSDriveInfo;
} // RemoveDrive

如果驱动器可以拆卸,方法应通过参数 drive 返回传递给方法的信息。 如果驱动器无法移除,方法应写出异常并返回 null。 如果你的服务提供者没有覆盖这个方法,默认实现会返回作为输入传递的驱动器信息。

初始化默认硬盘

你的硬盘提供商实现了 System.Management.Automation.Provider.DriveCmdletProvider.InitializeDefaultDrives* 方法来挂载硬盘。 例如,如果计算机加入了某个域,Active Directory 提供商可能会挂载一个驱动器以符合默认命名上下文。

该方法返回一组关于已初始化驱动器的信息,或一个空集合。 调用该方法的过程是在 Windows PowerShell 运行时调用 System.Management.Automation.Provider.CmdletProvider.Start* 方法以初始化提供者之后进行的。

该驱动器提供者不会覆盖 System.Management.Automation.Provider.DriveCmdletProvider.InitializeDefaultDrives* 方法。 然而,以下代码显示了默认实现,返回的是空驱动器集合:

关于实现初始化默认驱动器需要注意的事项

所有硬盘提供商都应该安装根驱动器,帮助用户更容易被发现。 根驱动器可能会列出作为其他挂载驱动器根的位置。 例如,Active Directory 提供商可能会创建一个驱动器,列出根分布式系统环境(DSE)属性中的 namingContext 命名上下文。 这有助于用户发现其他硬盘的挂载点。

代码示例

完整示例代码请参见 AccessDbProviderSample02 代码示例

测试Windows PowerShell驱动器提供者

当您的 Windows PowerShell 提供者已注册 Windows PowerShell 后,您可以通过命令行运行支持的 cmdlet(包括通过派生提供的 cmdlet)来测试。 让我们测试样品驱动器供应商。

  1. 运行 Get-PSProvider cmdlet 以获取提供者列表,以确保 AccessDB 驱动器提供者存在:

    附言>Get-PSProvider

    随即显示以下输出:

    Name                 Capabilities                  Drives
    ----                 ------------                  ------
    AccessDB             None                          {}
    Alias                ShouldProcess                 {Alias}
    Environment          ShouldProcess                 {Env}
    FileSystem           Filter, ShouldProcess         {C, Z}
    Function             ShouldProcess                 {function}
    Registry             ShouldProcess                 {HKLM, HKCU}
    
  2. 通过访问作系统管理工具的数据源部分,确保数据库存在数据库服务器名称(DSN)。 在 用户DSN 表中,双击 MS Access数据库 ,添加驱动器路径 C:\ps\northwind.mdb

  3. 使用样本驱动器提供商创建新驱动器:

    New-PSDrive -Name mydb -Root C:\ps\northwind.mdb -PSProvider AccessDb`
    

    随即显示以下输出:

    Name     Provider     Root                   CurrentLocation
    ----     --------     ----                   ---------------
    mydb     AccessDB     C:\ps\northwind.mdb
    
  4. 验证连接。 因为连接被定义为驱动器的成员,你可以用 Get-PDDrive cmdlet来检查。

    注释

    用户目前还不能以驱动器的形式与提供者交互,因为提供者需要容器功能来进行这种交互。 欲了解更多信息,请参见 创建 Windows PowerShell 容器提供者

    附言> (Get-PSDrive mydb)。连接

    随即显示以下输出:

    ConnectionString  : Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\ps\northwind.mdb
    ConnectionTimeout : 15
    Database          : C:\ps\northwind
    DataSource        : ACCESS
    ServerVersion     : 04.00.0000
    Driver            : odbcjt32.dll
    State             : Open
    Site              :
    Container         :
    
  5. 取出硬盘并退出外壳:

    PS> Remove-PSDrive mydb
    PS> exit
    

另请参阅

创建 Windows PowerShell 提供者

设计你的 Windows PowerShell 提供者

创建基础的 Windows PowerShell 提供者