ナビゲーション プロバイダーを記述する

このトピックでは、入れ子になったコンテナー (複数レベルのデータ ストア)、項目の移動、相対パスをサポートする 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 クラスによって公開されるメソッドを実装する方法については説明します。 項目コマンドレットを実装する方法を示す例については、「項目プロバイダーの作成 」を参照してください。 コンテナー コマンドレットを実装する方法を示す例については、「コンテナー プロバイダーの作成 」を参照してください

プロバイダー クラスの宣言

System.Management.Automation.Provider.Navigationcmdletproviderクラスから派生するプロバイダーを宣言し、System.Management.Automation.Provider.Cmdletproviderattributeで装飾します。

[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プロバイダーの概要」を参照してください。 ユーザーが Microsoft.PowerShell.Commands.JoinPathCommand コマンドレットを呼び出す場合、PowerShell エンジンは、このメソッドを呼び出します。

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*メソッドは、 パラメーターと パラメーターを受け取り、 パラメーターに相当し、 パラメーターに対する相対パスである正規化されたパスを返します。 path basepath 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 コマンドレットを呼び出す場合、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 プロバイダーの概要