次の方法で共有


Windows PowerShellナビゲーションプロバイダーの作成

このトピックでは、データストアをナビゲートできるWindows PowerShellナビゲーションプロバイダーの作成方法を説明します。 このタイプのプロバイダーは再帰コマンド、ネストコンテナ、相対パスをサポートします。

このプロバイダーのC#ソースファイル(AccessDBSampleProvider05.cs)は、Windows Vistaおよび.NET Framework 3.0ランタイムコンポーネント用のMicrosoft Windows Software Development Kitを使ってダウンロードできます。 ダウンロード手順については、「 Windows PowerShellのインストール方法」および「Windows PowerShell SDKのダウンロード」をご覧ください。 ダウンロードしたソースファイルは <PowerShell Samples> ディレクトリで利用可能です。 他のWindows PowerShellプロバイダー実装の詳細については、「 Windows PowerShell Providerの設計」をご覧ください。

ここで説明するプロバイダーは、ユーザーがAccessデータベースをドライブとして扱うことを可能にするもので、データベース内のデータテーブルへナビゲーションできます。 自分でナビゲーションプロバイダーを作成する際には、ドライブ限定パスをナビゲーションに必須にしたり、相対パスを正規化したり、データストアのアイテムを移動したり、子名を取得したり、アイテムの親パスを取得したり、アイテムがコンテナかどうかを判定したりするメソッドを実装できます。

注意事項

この設計は、名前IDを持つフィールドを持ち、そのフィールド型がLongIntegerであることを前提としています。

Windows PowerShellプロバイダーを定義してください

Windows PowerShellのナビゲーションプロバイダーは、 System.Management.Automation.Provider.NavigationCmdletProvider ベースクラスから派生した.NETクラスを作成しなければなりません。 この節で説明するナビゲーションプロバイダーのクラス定義はこちらです。

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

このプロバイダーでは、 System.Management.Automation.Provider.CmdletProviderAttribute 属性に2つのパラメータが含まれています。 最初のパラメータは、WindowsPowerShellで使用されるプロバイダーのユーザーフレンドリーな名前を指定します。 2つ目のパラメータは、コマンド処理中にプロバイダーがWindows PowerShellランタイムに公開するWindows PowerShell固有の能力を指定します。 このプロバイダーには、WindowsのPowerShell特有の機能が追加されていません。

基本機能の定義

Design Your PS Providerで説明されているように、 System.Management.Automation.Provider.NavigationCmdletProvider のベースクラスは、異なるプロバイダー機能を提供する複数のクラスから派生しています。 したがって、Windows PowerShellのナビゲーションプロバイダーは、これらのクラスが提供するすべての機能を定義しなければなりません。

セッション固有の初期化情報の追加や、プロバイダーが使用するリソースの解放機能の実装については、「 Basic PSプロバイダーの作成」を参照してください。 しかし、ほとんどのプロバイダー(ここで説明するプロバイダーを含む)は、Windows PowerShellが提供するこの機能のデフォルト実装を使用できます。

WindowsのPowerShellドライブを通じてデータストアにアクセスするには、 System.Management.Automation.Provider.DriveCmdletProvider のベースクラスのメソッドを実装する必要があります。 これらのメソッドの実装についての詳細は、「 Windows PowerShell Drive Providerの作成」をご覧ください。

データストアの項目、例えば取得、設定、クリアなどを操作するには、 プロバイダーはSystem.Management.Automation.Provider.ItemCmdletProvider ベースクラスが提供するメソッドを実装しなければなりません。 これらのメソッドの実装についての詳細は、「 Windows PowerShell Item Providerの作成」をご覧ください。

データストアの子項目やその名前、ならびにアイテムの作成、コピー、名前変更、削除を行うメソッドにアクセスするには、 System.Management.Automation.Provider.ContainerCmdletProvider ベースクラスが提供するメソッドを実装する必要があります。 これらのメソッドの実装についての詳細は、「 Windows PowerShellコンテナプロバイダーの作成」をご覧ください。

WindowsPowerShellパスの作成

Windows PowerShellナビゲーションプロバイダーは、データストアの項目をナビゲートするためにプロバイダー内部のWindows PowerShellパスを使用します。 プロバイダー内部パスを作成するには、 プロバイダーはSystem.Management.Automation.Provider.NavigationCmdletProvider.MakePath* メソッドを実装し、Combine-Path コマンドレットからの呼び出しをサポートする必要があります。 この方法は、親パスと子パスをプロバイダー固有のパス区切器を用いて、親パスと子パスを組み合わせてプロバイダー内部パスに変換します。

デフォルトの実装では、「/」または「\」がパスセパレーターとして使われ、パスセパレータを「\」に正規化し、親パスと子パス部分を区切りで組み合わせ、その後結合パスを含む文字列を返します。

このナビゲーションプロバイダーはこの手法を実装していません。 しかし、以下のコードは System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* メソッドのデフォルト実装です。

MakePathの実装について覚えておくべきこと

System.Management.Automation.Provider.NavigationCmdletProvider.MakePath*の実装には、以下の条件が適用される可能性があります:

  • System.Management.Automation.Provider.NavigationCmdletProvider.MakePath*メソッドの実装は、そのパスがプロバイダー名簿空間において法的に完全に適格なパスとして検証されるべきではありません。 各パラメータはパスの一部しか表現できず、結合した部分が完全に修飾されたパスを生成しない場合があります。 例えば、 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* メソッドは、 parent パラメータに「windows\system32」、 child パラメータに「abc.dll」を受け取ることがあります。 このメソッドはこれらの値を「\」区切りで結合し、「windows\system32\abc.dll」を返しますが、これは完全限定ファイルシステムパスではありません。

    Important

    System.Management.Automation.Provider.NavigationCmdletProvider.MakePath*への呼び出しで提供されるパス部分には、プロバイダー名前空間に許可されていない文字が含まれている場合があります。 これらの文字はおそらくワイルドカード拡張に使われており、この方法の実装で彼らが削除されるべきではありません。

親パスの取得

Windows PowerShellのナビゲーションプロバイダーは、 System.Management.Automation.Provider.NavigationCmdletProvider.GetParentPath* メソッドを実装し、指定された完全または部分的なプロバイダー固有のパスの親部分を取得します。 メソッドはパスの子部分を削除し、親パス部分を返します。 rootパラメータはドライブのルートへの完全限定パスを指定します。 このパラメータは、取得操作にマウントされたドライブが使用されていない場合、nullまたは空になることがあります。 ルートが指定されている場合、メソッドはルートと同じ木構造内のコンテナへのパスを返さなければなりません。

サンプルナビゲーションプロバイダーはこの方法を上書きせず、デフォルトの実装を使用します。 「/」と「\」の両方をパスセパレーターとして使うパスを受け入れます。 まずパスを「\」区切り器だけに正規化し、最後の「\」で親パスを分割して親パスを返します。

GetParentPathの実装について覚えておくために

System.Management.Automation.Provider.NavigationCmdletProvider.GetParentPath*メソッドの実装は、プロバイダー名空間のパス区切りで経路をレクシス的に分割するはずです。 例えば、FileSystemプロバイダーはこの方法で最後の「\」を探し、区切り子の左側にあるすべてを返します。

子パス名を取得する

ナビゲーションプロバイダーは System.Management.Automation.Provider.NavigationCmdletProvider.GetChildName* メソッドを実装し、指定された完全または部分的なプロバイダー固有パスにあるアイテムの子の名前(リーフ要素)を取得します。

サンプルナビゲーションプロバイダーはこの方法を上書きしません。 デフォルトの実装は以下の通りです。 「/」と「\」の両方をパスセパレーターとして使うパスを受け入れます。 まずパスを「\」区切り子だけに正規化し、親パスを最後の「\」で分割し、子パス部分の名前を返します。

GetChildNameの実装に関する注意点

System.Management.Automation.Provider.NavigationCmdletProvider.GetChildName*メソッドの実装は、パスセパレーター上でレクティックごとにパスを分割するはずです。 提供されたパスにパスセパレータがなければ、メソッドはそのパスを修正せずに返すべきです。

Important

このメソッドの呼び出しで提供されるパスには、プロバイダーの名前空間で違法な文字が含まれている場合があります。 これらの文字はおそらくワイルドカード展開や正則表現のマッチングに使われており、この手法の実装でそれらが削除されるべきではありません。

アイテムがコンテナかどうかの判定

ナビゲーションプロバイダーは System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* メソッドを実装し、指定されたパスがコンテナを示すかどうかを判定できます。 パスがコンテナを表す場合はtrue、そうでなければfalseを返します。 ユーザーは提供されたパスに対して Test-Path コマンドレットを使用できるように、このメソッドが必要です。

以下のコードは、サンプルナビゲーションプロバイダにおける System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* の実装を示しています。 このメソッドは指定されたパスが正しいか、テーブルが存在するかを検証し、パスがコンテナを示している場合はtrueを返します。

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

IsItemContainerの実装について覚えておくべきこと

ナビゲーションプロバイダーの.NETクラスは、 System.Management.Automation.Provider.ProviderCapabilities 列挙からExpandWildcards、Filter、Include、またはExcludeのプロバイダー能力を宣言することがあります。 この場合、 System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* の実装は、通過したパスが要件を満たしていることを保証する必要があります。 これを行うには、そのメソッドは適切なプロパティにアクセスする必要があります。例えば、 System.Management.Automation.Provider.CmdletProvider.Exclude* プロパティです。

アイテムの移動

Move-Itemコマンドレットをサポートするために、ナビゲーションプロバイダーはSystem.Management.Automation.Provider.NavigationCmdletProvider.MoveItem*メソッドを実装しています。 この方法は、 path パラメータで指定されたアイテムを destination パラメータで提供された経路のコンテナに移動させます。

サンプルナビゲーションプロバイダーは System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* メソッドを上書きしません。 以下はデフォルトの実装です。

MoveItemの実装について覚えておくべきこと

ナビゲーションプロバイダーの.NETクラスは、 System.Management.Automation.Provider.ProviderCapabilities 列挙からExpandWildcards、Filter、Include、またはExcludeのプロバイダー能力を宣言することがあります。 この場合、 System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* の実装は、通過したパスが要件を満たすことを保証します。 これを行うには、メソッドは適切なプロパティ、例えば CmdletProvider.Exclude プロパティにアクセスする必要があります。

デフォルトでは、このメソッドのオーバーライドは、 System.Management.Automation.Provider.CmdletProvider.Force* プロパティが trueに設定されていない限り、既存オブジェクトの上にオブジェクトを移動しません。 例えば、 FileSystemプロバイダーはSystem.Management.Automation.Provider.CmdletProvider.Force* プロパティが trueに設定されていない限り、既存の C:\bar.txt ファイルに C:\temp\abc.txt をコピーしません。 destinationパラメータで指定されたパスが存在しコンテナであれば、System.Management.Automation.Provider.CmdletProvider.Force*プロパティは必須ではありません。 この場合、 System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* は、 path パラメータで示されたアイテムを destination パラメータで示されるコンテナに子として移動させるべきです。

System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem*メソッドの実装は、データストアに変更を加える前にSystem.Management.Automation.Provider.CmdletProvider.ShouldProcessを呼び出し、返却値を確認すべきです。 このメソッドは、システム状態に変更があった場合、例えばファイルの削除などが行われた際に操作の実行を確認するために使用されます。 System.Management.Automation.Provider.CmdletProvider.ShouldProcess は、変更するリソース名をユーザーに送信し、Windows PowerShellランタイムはコマンドラインの設定や好み変数を考慮して、ユーザーに表示すべき内容を決定します。

System.Management.Automation.Provider.CmdletProvider.ShouldProcessへの呼び出しが返true後、System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem*メソッドはSystem.Management.Automation.Provider.CmdletProvider.CommandletProvider.ShouldContinueメソッドを呼び出します。 このメソッドは、操作を継続すべきかどうかをユーザーにフィードバックするためのメッセージを送信します。 プロバイダーは、潜在的に危険なシステム変更の追加チェックとして System.Management.Automation.Provider.CommandletProvider.WithWithEnter に連絡してください。

Move-Item コマンドレットへの動的パラメータの付与

時には Move-Item コマンドレットが実行時に動的に追加パラメータを必要とすることもあります。 これらの動的パラメータを提供するために、ナビゲーションプロバイダーは System.Management.Automation.Provider.NavigationCmdletProvider.MoveItemDynamicParameters* メソッドを実装し、指定されたパスのアイテムから必要なパラメータ値を取得し、コマンドレットクラスや System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトに似た解析属性を持つプロパティとフィールドを持つオブジェクトを返す必要があります。

このナビゲーションプロバイダーはこの手法を実装していません。 しかし、以下のコードは System.Management.Automation.Provider.NavigationCmdletProvider.MoveItemDynamicParameters*のデフォルト実装です。

相対経路の正規化

ナビゲーションプロバイダーは System.Management.Automation.Provider.NavigationCmdletProvider.NormalizeRelativePath* メソッドを実装し、 path パラメータで示された完全修飾パスを basePath パラメータで指定されたパスと相対的に正規化します。 このメソッドは正規化されたパスの文字列表現を返します。 pathパラメータが存在しない経路を指定する場合、エラーを書き込みます。

サンプルナビゲーションプロバイダーはこの方法を上書きしません。 以下はデフォルトの実装です。

NormalizeRelativePathの実装について覚えておくべきこと

System.Management.Automation.Provider.NavigationCmdletProvider.NormalizeRelativePath*の実装はpathパラメータを解析するはずですが、純粋に構文解析のみを使う必要はありません。 この方法を設計して、パスを使ってデータストア内のパス情報を調べ、ケーシングや標準化されたパス構文に合致するパスを作成することが推奨されます。

コード サンプル

完全なサンプルコードについては、 AccessDbProviderSample05 Code Sampleをご覧ください。

オブジェクトタイプの定義と書式設定

プロバイダーは既存のオブジェクトにメンバーを追加したり、新しいオブジェクトを定義したりすることが可能です。 詳細については、「オブジェクトタイプとフォーマットの拡張」をご覧ください。

Windows PowerShellプロバイダーの構築

詳細については、「 コマンドレット、プロバイダー、ホストアプリケーションの登録方法」をご覧ください。

Windows PowerShellプロバイダーのテスト

Windows PowerShellプロバイダーがWindows PowerShellに登録されたら、コマンドラインでサポート済みのコマンドレットを実行し、派生で提供されるコマンドレットも含めてテストできます。 この例ではサンプルナビゲーションプロバイダーをテストします。

  1. 新しいシェルを実行し、 Set-Location コマンドレットを使ってAccessデータベースを示すパスを設定します。

    Set-Location mydb:
    
  2. 次に Get-ChildItem コマンドレットを実行して、利用可能なデータベースの項目リストを取得します。 各テーブルに対して、このコマンドレットはテーブルの行数も取得します。

    Get-ChildItem | Format-Table RowCount, Name -AutoSize
    
    RowCount   Name
    --------   ----
         180   MSysAccessObjects
           0   MSysACEs
           1   MSysCmdbars
           0   MSysIMEXColumns
           0   MSysIMEXSpecs
           0   MSysObjects
           0   MSysQueries
           7   MSysRelationships
           8   Categories
          91   Customers
           9   Employees
        2155   Order Details
         830   Orders
          77   Products
           3   Shippers
          29   Suppliers
    
  3. 再度 Set-Location コマンドレットを使って従業員のデータテーブルの位置を設定します。

    Set-Location Employees
    
  4. 次に Get-Location コマンドレットを使ってEmployeesテーブルへのパスを取得します。

    Get-Location
    
    Path
    ----
    mydb:\Employees
    
  5. 次に Get-ChildItem コマンドレットをそのコマンドレットにパイプ Format-Table 接続します。 このコマンドレットのセットは、従業員データテーブルの項目、すなわちテーブル行を取得します。 これらは Format-Table コマンドレットで指定されたフォーマットになっています。

    Get-ChildItem | Format-Table RowNumber, PSIsContainer, Data -AutoSize
    
    RowNumber   PSIsContainer   Data
    ---------   --------------   ----
    0           False            System.Data.DataRow
    1           False            System.Data.DataRow
    2           False            System.Data.DataRow
    3           False            System.Data.DataRow
    4           False            System.Data.DataRow
    5           False            System.Data.DataRow
    6           False            System.Data.DataRow
    7           False            System.Data.DataRow
    8           False            System.Data.DataRow
    
  6. これで Get-Item コマンドレットを実行して、従業員データテーブルの0行目に項目を取得できます。

    Get-Item 0
    
    PSPath        : AccessDB::C:\PS\Northwind.mdb\Employees\0
    PSParentPath  : AccessDB::C:\PS\Northwind.mdb\Employees
    PSChildName   : 0
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : False
    Data           : System.Data.DataRow
    RowNumber      : 0
    
  7. Get-Itemコマンドレットを再度使い、行0の項目の従業員データを取得します。

    (Get-Item 0).Data
    
    EmployeeID      : 1
    LastName        : Davis
    FirstName       : Sara
    Title           : Sales Representative
    TitleOfCourtesy : Ms.
    BirthDate       : 12/8/1968 12:00:00 AM
    HireDate        : 5/1/1992 12:00:00 AM
    Address         : 4567 Main Street
                      Apt. 2A
    City            : Buffalo
    Region          : NY
    PostalCode      : 98052
    Country         : USA
    HomePhone       : (206) 555-9857
    Extension       : 5467
    Photo           : EmpID1.bmp
    Notes           : Education includes a BA in psychology from
                      Colorado State University. She also completed "The
                      Art of the Cold Call."  Nancy is a member of
                      Toastmasters International.
    ReportsTo       : 2
    

こちらもご覧ください

Windows PowerShellプロバイダーの作成

Windows PowerShellプロバイダーを設計する

オブジェクトタイプとフォーマットの拡張

Implement a Container Windows PowerShell provider

コマンドレット、プロバイダー、ホストアプリケーションの登録方法

Windows PowerShell プログラマーズガイド

Windows PowerShell SDK