次の方法で共有


Windows PowerShell アイテム提供者の作成

このトピックでは、データストア内のデータを操作できるWindowsのPowerShellプロバイダーの作成方法について説明します。 このトピックでは、ストア内のデータの要素を「アイテム」と呼びます。 その結果、ストア内のデータを操作できるプロバイダーはWindows PowerShellアイテムプロバイダーと呼ばれます。

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

このトピックで説明するWindows PowerShellのアイテムプロバイダーは、Accessデータベースからアイテムを取得します。 この場合、「アイテム」とはAccessデータベース内のテーブルかテーブル内の行のいずれかです。

Windows PowerShell item provider class の定義

Windows PowerShellのアイテムプロバイダーは、 System.Management.Automation.Provider.ItemCmdletProvider のベースクラスから派生する.NETクラスを定義しなければなりません。 以下は、この節で説明するアイテム提供者のクラス定義です。

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

public class AccessDBProvider : ItemCmdletProvider

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

基本機能の定義

Windows PowerShell Providerを設計する」で説明されているように、 System.Management.Automation.Provider.DriveCmdletProvider クラスは、異なるプロバイダー機能を提供する複数の他のクラスから派生しています。 したがって、Windows PowerShellのアイテムプロバイダーは、これらのクラスが提供するすべての機能を定義しなければなりません。

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

Windows PowerShellのアイテムプロバイダーがストア内のアイテムを操作する前に、 System.Management.Automation.Provider.DriveCmdletProvider のベースクラスのメソッドを実装してデータストアにアクセスする必要があります。 このクラスの実装についての詳細は、「 Windows PowerShell Drive Providerの作成」を参照してください。

経路妥当性の検証

データ項目を探す際、Windows PowerShellランタイムは「 Windows PowerShell Works」の「PSPath Concepts」セクションで定義されたように、プロバイダーへのWindows PowerShellパスを提供します。 Windows PowerShellのアイテムプロバイダーは、 System.Management.Automation.Provider.ItemCmdletProvider.IsValidPath メソッドを実装して、渡されたパスの構文的および意味的妥当性を検証しなければなりません。 このメソッドはパスが有効であれば true を返し、そうでなければ返 false します。 このメソッドの実装は、パス上のアイテムの存在を検証するのではなく、そのパスが構文的・意味的に正しいかどうかのみを検証するものであることに注意してください。

こちらはこのプロバイダーに対する System.Management.Automation.Provider.ItemCmdletProvider.IsValidPath メソッドの実装です。 この実装では 、NormalizePath ヘルパーメソッドを呼び出して、パス内のすべてのセパレーターを一様なものに変換します。

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

アイテムが存在するかどうかの判定

パスを検証した後、Windows PowerShellランタイムはそのパスにデータ項目が存在するかどうかを判断しなければなりません。 この種のクエリをサポートするために、Windows PowerShellのアイテムプロバイダーは System.Management.Automation.Provider.ItemCmdletProvider.ItemExists メソッドを実装しています。 このメソッドは指定されたパスでアイテムが見つかる true 返し、そうでなければ(デフォルト) false 返します。

こちらはこのプロバイダーの System.Management.Automation.Provider.ItemCmdletProvider.ItemExists メソッドの実装です。 このメソッドは PathIsDriveChunkPathGetTable の各ヘルパーメソッドを呼び出し、プロバイダー定義の DatabaseTableInfo オブジェクトを使用します。

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;

} // ItemExists

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

System.Management.Automation.Provider.ItemCmdletProvider.ItemExistsの実装には、以下の条件が適用される場合があります:

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

時には、System.Management.Automation.Provider.ItemCmdletProvider.ItemExistsを呼び出すTest-Pathコマンドレットが、実行時に動的に指定される追加パラメータを必要とすることがあります。 これらの動的パラメータを提供するためには、WindowsPowerShellのアイテムプロバイダーが System.Management.Automation.Provider.ItemCmdletProvider.ItemExistsDynamicParameters メソッドを実装する必要があります。 このメソッドは指定されたパス上のアイテムの動的パラメータを取得し、コマンドレットクラスや System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトに似た解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShellランタイムは、返されたオブジェクトを使ってパラメータを Test-Path コマンドレットに追加します。

このWindows PowerShellのアイテムプロバイダーはこのメソッドを実装していません。 しかし、以下のコードはこのメソッドのデフォルトの実装です。

アイテムの取得

アイテムを取得するには、Windows PowerShellのアイテムプロバイダーが System.Management.Automation.Provider.ItemCmdletProvider.GetItem メソッドをオーバーライドし、 Get-Item コマンドレットからの呼び出しをサポートする必要があります。 このメソッドは System.Management.Automation.Provider.CmdletProvider.WriteItemObject メソッドを使ってアイテムを書き込みます。

こちらはこのプロバイダーの System.Management.Automation.Provider.ItemCmdletProvider.GetItem メソッドの実装です。 このメソッドは GetTable および GetRow ヘルパーメソッドを使用して、Accessデータベース内のテーブルやデータテーブル内の行のいずれかを取得することに注意してください。

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

 } // GetItem

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

System.Management.Automation.Provider.ItemCmdletProvider.GetItemの実装には、以下の条件が適用されることがあります:

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

時には Get-Item コマンドレットが実行時に動的に指定される追加パラメータを必要とすることもあります。 これらの動的パラメータを提供するために、WindowsPowerShellのアイテム提供者は System.Management.Automation.Provider.ItemCmdletProvider.GetItemDynamicParameters メソッドを実装しなければなりません。 このメソッドは指定されたパス上のアイテムの動的パラメータを取得し、コマンドレットクラスや System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトに似た解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShellランタイムは、返されたオブジェクトを使ってパラメータを Get-Item コマンドレットに追加します。

このプロバイダーはこの手法を実装していません。 しかし、以下のコードはこのメソッドのデフォルトの実装です。

アイテムの設定

アイテムを設定するには、Windows PowerShellのアイテムプロバイダーが System.Management.Automation.Provider.ItemCmdletProvider.SetItem メソッドをオーバーライドし、 Set-Item コマンドレットからの呼び出しをサポートしなければなりません。 このメソッドは指定された経路におけるアイテムの値を設定します。

このプロバイダーは System.Management.Automation.Provider.ItemCmdletProvider.SetItem メソッドのオーバーライドを提供しません。 しかし、以下はこの手法のデフォルトの実装です。

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

System.Management.Automation.Provider.ItemCmdletProvider.SetItemの実装には、以下の条件が適用される場合があります:

SetItemの動的パラメータの取得

時には Set-Item コマンドレットが実行時に動的に指定される追加パラメータを必要とすることもあります。 これらの動的パラメータを提供するためには、WindowsPowerShellのアイテム提供者が System.Management.Automation.Provider.ItemCmdletProvider.SetItemDynamicParameters メソッドを実装する必要があります。 このメソッドは指定されたパス上のアイテムの動的パラメータを取得し、コマンドレットクラスや System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトに似た解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShellランタイムは、返されたオブジェクトを使ってパラメータを Set-Item コマンドレットに追加します。

このプロバイダーはこの手法を実装していません。 しかし、以下のコードはこのメソッドのデフォルトの実装です。

アイテムのクリアリング

アイテムをクリアするために、Windows PowerShellのアイテムプロバイダーは System.Management.Automation.Provider.ItemCmdletProvider.ClearItem メソッドを実装し、 Clear-Item コマンドレットからの呼び出しをサポートします。 この方法は指定されたパスでデータ項目を消去します。

このプロバイダーはこの手法を実装していません。 しかし、以下のコードはこのメソッドのデフォルトの実装です。

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

System.Management.Automation.Provider.ItemCmdletProvider.ClearItemの実装には、以下の条件が適用されることがあります:

ClearItemの動的パラメータを取得する

時には Clear-Item コマンドレットが実行時に動的に指定される追加パラメータを必要とすることもあります。 これらの動的パラメータを提供するために、Windows PowerShellのアイテム提供者は System.Management.Automation.Provider.ItemCmdletProvider.ClearItemDynamicParameters メソッドを実装する必要があります。 このメソッドは指定されたパス上のアイテムの動的パラメータを取得し、コマンドレットクラスや System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトに似た解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShellランタイムは、返されたオブジェクトを使ってパラメータを Clear-Item コマンドレットに追加します。

このアイテムプロバイダーはこのメソッドを実装していません。 しかし、以下のコードはこのメソッドのデフォルトの実装です。

アイテムのデフォルトアクションを実行する

Windows PowerShellのアイテムプロバイダーは、 System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction メソッドを実装し、 Invoke-Item コマンドレットからの呼び出しをサポートすることで、指定されたパス上のアイテムに対してデフォルトアクションを実行できます。 例えば、FileSystemプロバイダーはこのメソッドを使って特定のアイテムに対して ShellExecute を呼び出すことがあります。

このプロバイダーはこの手法を実装していません。 しかし、以下のコードはこのメソッドのデフォルトの実装です。

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

System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultActionの実装には、以下の条件が適用される場合があります:

InvokeDefaultAction の動的パラメータを取得する

時には Invoke-Item コマンドレットが実行時に動的に指定される追加パラメータを必要とすることもあります。 これらの動的パラメータを提供するためには、WindowsPowerShellのアイテム提供者が System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultActionDynamicParameters メソッドを実装する必要があります。 このメソッドは指定されたパス上のアイテムの動的パラメータを取得し、コマンドレットクラスや System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトに似た解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShellランタイムは、返されたオブジェクトを使って Invoke-Item コマンドレットに動的パラメータを追加します。

このアイテムプロバイダーはこのメソッドを実装していません。 しかし、以下のコードはこのメソッドのデフォルトの実装です。

ヘルパーメソッドとクラスの実装

このアイテムプロバイダーは、Windows PowerShellで定義されたパブリックオーバーライドメソッドで使用される複数のヘルパーメソッドやクラスを実装しています。 これらのヘルパーメソッドとクラスのコードは「 Code Sample 」セクションに示されています。

正規化パス法

このアイテム提供者は、パスのフォーマットが一貫していることを保証するために NormalizePath ヘルパーメソッドを実装しています。 指定されたフォーマットは区切りとしてバックスラッシュ(\)を使用しています。

PathIsDriveメソッド

このアイテムプロバイダーは、指定されたパスが実際にドライブ名であるかどうかを判定する PathIsDrive ヘルパーメソッドを実装しています。

チャンクパス法

このアイテムプロバイダーは、指定されたパスを分割してプロバイダーが個々の要素を識別できるようにする ChunkPath ヘルパーメソッドを実装しています。 パス要素からなる配列を返します。

GetTableメソッド

このアイテムプロバイダーは、呼び出しで指定されたテーブルに関する情報を表すDatabaseTableInfoオブジェクトを返すGetTablesヘルパーメソッドを実装しています。

GetRow メソッド

System.Management.Automation.Provider.ItemCmdletProvider.GetItemメソッドは、GetRowsヘルパーメソッドを呼び出します。 このヘルパーメソッドは、テーブル内の指定された行に関する情報を表す DatabaseRowInfo オブジェクトを取得します。

DatabaseTableInfoクラス

このアイテム提供者は、データベース内のデータテーブル内の情報の集合を表す DatabaseTableInfo クラスを定義します。 このクラスは System.IO.Directoryinfo クラスに似ています。

サンプルアイテム提供者は、データベース内のテーブルを定義するテーブル情報オブジェクトの集合を返す DatabaseTableInfo.GetTables メソッドを定義しています。 このメソッドにはtry/catchブロックが含まれており、データベースエラーがエントリがゼロの行として表示されるようにします。

DatabaseRowInfo クラス

このアイテム提供者は、データベースのテーブル内の行を表す DatabaseRowInfo ヘルパークラスを定義します。 このクラスは System.IO.FileInfo クラスに似ています。

サンプルプロバイダーは、指定されたテーブルの行情報オブジェクトの集合を返すための DatabaseRowInfo.GetRows メソッドを定義しています。 この方法には例外をトラップするためのtry/catchブロックが含まれています。 誤りがあれば行情報がなくなります。

コード サンプル

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

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

プロバイダーを書く際には、既存のオブジェクトにメンバーを追加したり、新しいオブジェクトを定義したりする必要がある場合があります。 完了後、Windows PowerShellがオブジェクトのメンバーを識別できるTypesファイルと、オブジェクトの表示方法を定義するFormatファイルを作成します。 詳細については、「 オブジェクトタイプとフォーマットの拡張」をご覧ください。

Windows PowerShellプロバイダーの構築

コマンドレット、プロバイダー、ホスティングアプリケーションの登録方法」を参照してください。

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

このWindows PowerShellアイテムプロバイダーがWindows PowerShellに登録されている場合、プロバイダの基本機能とドライブ機能のみをテストできます。 アイテム操作をテストするには、「 Implementing a Container Windows PowerShell Provider」で説明されているコンテナ機能も実装する必要があります。

こちらも参照ください