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

[玩转系统] 编写导航提供程序

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

编写导航提供程序


本主题介绍如何实现支持嵌套容器(多级数据存储)、移动项目和相对路径的 Windows PowerShell 提供程序的方法。导航提供程序必须从 System.Management.Automation.Provider.Navigationcmdletprovider 类派生。

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

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

实现导航方法

System.Management.Automation.Provider.Navigationcmdletprovider 类实现支持嵌套容器、相对路径和移动项目的方法。有关这些方法的完整列表,请参阅 NavigationCmdletProvider 方法。

笔记

本主题基于 Windows PowerShell 提供程序快速入门中的信息构建。本主题不介绍如何设置提供程序项目或如何实现从 System.Management.Automation.Provider.Drivecmdletprovider 类继承的用于创建和删除驱动器的方法的基础知识。本主题也不介绍如何实现 System.Management.Automation.Provider.Itemcmdletprovider 或 System.Management.Automation.Provider.Containercmdletprovider 类公开的方法。有关演示如何实现项目 cmdlet 的示例,请参阅编写项目提供程序。有关演示如何实现容器 cmdlet 的示例,请参阅编写容器提供程序。

声明提供者类

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

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

   }

实现 IsItemContainer

System.Management.Automation.Provider.Navigationcmdletprovider.Isitemcontainer* 方法检查指定路径处的项目是否是容器。

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

实现 GetChildName

System.Management.Automation.Provider.Navigationcmdletprovider.Getchildname* 方法获取指定路径处子项的 name 属性。如果指定路径处的项目不是容器的子项,则此方法应返回该路径。

protected override string GetChildName(string path)
       {
           if (PathIsDrive(path))
           {
               return path;
           }

           string tableName;
           int rowNumber;

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

           if (type == PathType.Table)
           {
               return tableName;
           }
           else if (type == PathType.Row)
           {
               return rowNumber.ToString(CultureInfo.CurrentCulture);
           }
           else
           {
               ThrowTerminatingInvalidPathException(path);
           }

           return null;
       }

实现 GetParentPath

System.Management.Automation.Provider.Navigationcmdletprovider.Getparentpath* 方法获取指定路径处的项目父级的路径。如果指定路径处的项目是数据存储的根(因此它没有父级),则此方法应返回根路径。

protected override string GetParentPath(string path, string root)
       {
           // If root is specified then the path has to contain
           // the root. If not nothing should be returned
           if (!String.IsNullOrEmpty(root))
           {
               if (!path.Contains(root))
               {
                   return null;
               }
           }

           return path.Substring(0, path.LastIndexOf(pathSeparator, StringComparison.OrdinalIgnoreCase));
       }

实施MakePath

System.Management.Automation.Provider.Navigationcmdletprovider.Makepath* 方法连接指定的父路径和指定的子路径以创建提供程序内部路径(有关提供程序可以支持的路径类型的信息,请参阅 Windows PowerShell 提供程序概述。PowerShell当用户调用 Microsoft.PowerShell.Commands.JoinPathCommand cmdlet 时,引擎会调用此方法。

protected override string MakePath(string parent, string child)
       {
           string result;

           string normalParent = NormalizePath(parent);
           normalParent = RemoveDriveFromPath(normalParent);
           string normalChild = NormalizePath(child);
           normalChild = RemoveDriveFromPath(normalChild);

           if (String.IsNullOrEmpty(normalParent) && String.IsNullOrEmpty(normalChild))
           {
               result = String.Empty;
           }
           else if (String.IsNullOrEmpty(normalParent) && !String.IsNullOrEmpty(normalChild))
           {
               result = normalChild;
           }
           else if (!String.IsNullOrEmpty(normalParent) && String.IsNullOrEmpty(normalChild))
           {
               if (normalParent.EndsWith(pathSeparator, StringComparison.OrdinalIgnoreCase))
               {
                   result = normalParent;
               }
               else
               {
                   result = normalParent + pathSeparator;
               }
           } // else if (!String...
           else
           {
               if (!normalParent.Equals(String.Empty) &&
                   !normalParent.EndsWith(pathSeparator, StringComparison.OrdinalIgnoreCase))
               {
                   result = normalParent + pathSeparator;
               }
               else
               {
                   result = normalParent;
               }

               if (normalChild.StartsWith(pathSeparator, StringComparison.OrdinalIgnoreCase))
               {
                   result += normalChild.Substring(1);
               }
               else
               {
                   result += normalChild;
               }
           } // else

           return result;
       }

实现 NormalizeRelativePath

System.Management.Automation.Provider.Navigationcmdletprovider.Normalizerelativepath* 方法采用 pathbasepath 参数,并返回与 path 等效的规范化路径 参数并相对于 basepath 参数。

protected override string NormalizeRelativePath(string path,
                                                            string basepath)
       {
           // Normalize the paths first
           string normalPath = NormalizePath(path);
           normalPath = RemoveDriveFromPath(normalPath);
           string normalBasePath = NormalizePath(basepath);
           normalBasePath = RemoveDriveFromPath(normalBasePath);

           if (String.IsNullOrEmpty(normalBasePath))
           {
               return normalPath;
           }
           else
           {
               if (!normalPath.Contains(normalBasePath))
               {
                   return null;
               }

               return normalPath.Substring(normalBasePath.Length + pathSeparator.Length);
           }
       }

实施MoveItem

System.Management.Automation.Provider.Navigationcmdletprovider.Moveitem* 方法将项目从指定路径移动到指定目标路径。当用户调用 Microsoft.PowerShell.Commands.MoveItemCommand cmdlet 时,PowerShell 引擎会调用此方法。

protected override void MoveItem(string path, string destination)
       {
           // Get type, table name and rowNumber from the path
           string tableName, destTableName;
           int rowNumber, destRowNumber;

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

           PathType destType = GetNamesFromPath(destination, out destTableName,
                                    out destRowNumber);

           if (type == PathType.Invalid)
           {
               ThrowTerminatingInvalidPathException(path);
           }

           if (destType == PathType.Invalid)
           {
               ThrowTerminatingInvalidPathException(destination);
           }

           if (type == PathType.Table)
           {
               ArgumentException e = new ArgumentException("Move not supported for tables");

               WriteError(new ErrorRecord(e, "MoveNotSupported",
                   ErrorCategory.InvalidArgument, path));

               throw e;
           }
           else
           {
               OdbcDataAdapter da = GetAdapterForTable(tableName);
               if (da == null)
               {
                   return;
               }

               DataSet ds = GetDataSetForTable(da, tableName);
               DataTable table = GetDataTable(ds, tableName);

               OdbcDataAdapter dda = GetAdapterForTable(destTableName);
               if (dda == null)
               {
                   return;
               }

               DataSet dds = GetDataSetForTable(dda, destTableName);
               DataTable destTable = GetDataTable(dds, destTableName);
               DataRow row = table.Rows[rowNumber];

               if (destType == PathType.Table)
               {
                   DataRow destRow = destTable.NewRow();

                   destRow.ItemArray = row.ItemArray;
               }
               else
               {
                   DataRow destRow = destTable.Rows[destRowNumber];

                   destRow.ItemArray = row.ItemArray;
               }

               // Update the changes
               if (ShouldProcess(path, "MoveItem"))
               {
                   WriteItemObject(row, path, false);
                   dda.Update(dds, destTableName);
               }
           }
       }

参见

编写容器提供程序

Windows PowerShell 提供程序概述

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

取消回复欢迎 发表评论:

关灯