このトピックでは、データストアをナビゲートできる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に登録されたら、コマンドラインでサポート済みのコマンドレットを実行し、派生で提供されるコマンドレットも含めてテストできます。 この例ではサンプルナビゲーションプロバイダーをテストします。
新しいシェルを実行し、
Set-Locationコマンドレットを使ってAccessデータベースを示すパスを設定します。Set-Location mydb:次に
Get-ChildItemコマンドレットを実行して、利用可能なデータベースの項目リストを取得します。 各テーブルに対して、このコマンドレットはテーブルの行数も取得します。Get-ChildItem | Format-Table RowCount, Name -AutoSizeRowCount 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再度
Set-Locationコマンドレットを使って従業員のデータテーブルの位置を設定します。Set-Location Employees次に
Get-Locationコマンドレットを使ってEmployeesテーブルへのパスを取得します。Get-LocationPath ---- mydb:\Employees次に
Get-ChildItemコマンドレットをそのコマンドレットにパイプFormat-Table接続します。 このコマンドレットのセットは、従業員データテーブルの項目、すなわちテーブル行を取得します。 これらはFormat-Tableコマンドレットで指定されたフォーマットになっています。Get-ChildItem | Format-Table RowNumber, PSIsContainer, Data -AutoSizeRowNumber 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これで
Get-Itemコマンドレットを実行して、従業員データテーブルの0行目に項目を取得できます。Get-Item 0PSPath : 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 : 0Get-Itemコマンドレットを再度使い、行0の項目の従業員データを取得します。(Get-Item 0).DataEmployeeID : 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
こちらもご覧ください
Implement a Container Windows PowerShell provider