当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 编写项目提供者

作者:精品下载站 日期:2024-12-14 02:47:02 浏览:14 分类:玩电脑

编写项目提供者


本主题介绍如何实现 Windows PowerShell 提供程序访问和操作数据存储中的项目的方法。为了能够访问项目,提供程序必须从 System.Management.Automation.Provider.Itemcmdletprovider 类派生。

本主题示例中的提供程序使用 Access 数据库作为其数据存储。有几种用于与数据库交互的辅助方法和类。有关包含辅助方法的完整示例,请参阅 AccessDBProviderSample03

有关 Windows PowerShell 提供程序的详细信息,请参阅 Windows PowerShell 提供程序概述。

实施项目方法

System.Management.Automation.Provider.Itemcmdletprovider 类公开了多种可用于访问和操作数据存储中的项目的方法。有关这些方法的完整列表,请参阅 ItemCmdletProvider 方法。在此示例中,我们将实现其中四种方法。 System.Management.Automation.Provider.Itemcmdletprovider.Getitem* 获取指定路径处的项目。 System.Management.Automation.Provider.Itemcmdletprovider.Setitem* 设置指定项目的值。 System.Management.Automation.Provider.Itemcmdletprovider.Itemexists* 检查指定路径中是否存在项目。 System.Management.Automation.Provider.Itemcmdletprovider.Isvalidpath* 检查路径以查看它是否映射到数据存储中的某个位置。

笔记

本主题基于 Windows PowerShell 提供程序快速入门中的信息构建。本主题不介绍如何设置提供程序项目或如何实现从 System.Management.Automation.Provider.Drivecmdletprovider 类继承的用于创建和删除驱动器的方法的基础知识。

声明提供者类

声明提供程序从 System.Management.Automation.Provider.Itemcmdletprovider 类派生,并使用 System.Management.Automation.Provider.Cmdletprovider 属性对其进行修饰。

[CmdletProvider("AccessDB", ProviderCapabilities.None)]

   public class AccessDBProvider : ItemCmdletProvider
   {

  }

实现 GetItem

当用户在提供程序上调用 Microsoft.PowerShell.Commands.GetItemCommand cmdlet 时,PowerShell 引擎将调用 System.Management.Automation.Provider.Itemcmdletprovider.Getitem*。该方法返回指定路径处的项目。在 Access 数据库示例中,该方法检查该项目是驱动器本身、数据库中的表还是数据库中的行。该方法通过调用 System.Management.Automation.Provider.Cmdletprovider.Writeitemobject* 方法将项目发送到 PowerShell 引擎。

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);
           }

       }

实现SetItem

当用户调用 Microsoft.PowerShell.Commands.SetItemCommand cmdlet 时,PowerShell 引擎调用将调用 System.Management.Automation.Provider.Itemcmdletprovider.Setitem* 方法。它设置指定路径中项目的值。

在 Access 数据库示例中,仅当项目是行时才设置该项目的值才有意义,因此当项目不是行时该方法将引发 NotSupportedException。

protected override void SetItem(string path, object values)
       {
           // Get type, table name and row number from the path specified
           string tableName;
           int rowNumber;

           PathType type = GetNamesFromPath(path, out tableName, out rowNumber);

           if (type != PathType.Row)
           {
               WriteError(new ErrorRecord(new NotSupportedException(
                     "SetNotSupported"), "",
                  ErrorCategory.InvalidOperation, path));

               return;
           }

           // Get in-memory representation of table
           OdbcDataAdapter da = GetAdapterForTable(tableName);

           if (da == null)
           {
               return;
           }
           DataSet ds = GetDataSetForTable(da, tableName);
           DataTable table = GetDataTable(ds, tableName);

           if (rowNumber >= table.Rows.Count)
           {
               // The specified row number has to be available. If not
               // NewItem has to be used to add a new row
               throw new ArgumentException("Row specified is not available");
           } // if (rowNum...

           string[] colValues = (values as string).Split(',');

           // set the specified row
           DataRow row = table.Rows[rowNumber];

           for (int i = 0; i < colValues.Length; i++)
           {
               row[i] = colValues[i];
           }

           // Update the table
           if (ShouldProcess(path, "SetItem"))
           {
               da.Update(ds, tableName);
           }

       }

实施 ItemExists

当用户调用 Microsoft.PowerShell.Commands.TestPathCommand cmdlet 时,PowerShell 引擎会调用 System.Management.Automation.Provider.Itemcmdletprovider.Itemexists* 方法。该方法确定指定路径上是否存在项目。如果该项目确实存在,该方法将通过调用 System.Management.Automation.Provider.Cmdletprovider.Writeitemobject* 将其传递回 PowerShell 引擎。

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;

       }

实现 IsValidPath

System.Management.Automation.Provider.Itemcmdletprovider.Isvalidpath* 方法检查指定的路径对于当前提供程序在语法上是否有效。它不检查路径中是否存在项目。

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;
       }

后续步骤

典型的现实世界提供者能够支持包含其他项目的项目,并能够将项目从驱动器内的一个路径移动到另一路径。有关支持容器的提供程序的示例,请参阅编写容器提供程序。有关支持移动项目的提供程序的示例,请参阅编写导航提供程序。

参见

编写容器提供程序

编写导航提供程序

Windows PowerShell 提供程序概述

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯