Windows PowerShell項目プロバイダーの作成

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

注意

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

このトピックで説明するWindows PowerShell項目プロバイダーは、Access データベースからデータの項目を取得します。 この場合、"item" は Access データベース内のテーブルまたはテーブル内の行です。

Windows PowerShell項目プロバイダー クラスの定義

Windows PowerShell項目プロバイダーは、System.Management.Automation.Provider.ItemCmdletProvider 基本クラスから派生する .NET クラスを定義する必要があります。 このセクションで説明する項目プロバイダーのクラス定義を次に示します。

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

public class AccessDBProvider : ItemCmdletProvider

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

基本機能の定義

「Windows PowerShell プロバイダーの設計」で説明されているように、System.Management.Automation.Provider.DriveCmdletProvider クラスは、プロバイダー機能が異なる他のいくつかのクラスから派生します。 したがって、Windows PowerShell項目プロバイダーは、これらのクラスによって提供されるすべての機能を定義する必要があります。

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

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

パスの有効性の確認

データの項目を探すとき、Windows PowerShell ランタイムは、プロバイダーへのWindows PowerShell パスを提供します。これは、「Windows PowerShellのしくみ」の「PSPath の概念」セクションで定義されています。 Windows PowerShell項目プロバイダーは、System.Management.Automation.Provider.ItemCmdletProvider.IsValidPath メソッドを実装することで、渡されたパスの構文とセマンティックの有効性を確認する必要があります。 このメソッドは、パスが有効な場合は返しfalse、それ以外の場合は返しますtrue。 このメソッドの実装では、パスに項目が存在することを確認するのではなく、パスが構文的かつ意味的に正しいことを確認する必要があることに注意してください。

このプロバイダーの 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 メソッドの実装を次に示します。 このメソッドは PathIsDriveChunkPath、および GetTable ヘルパー メソッドを呼び出し、プロバイダー定義 の 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 コマンドレットへの動的パラメーターのアタッチ

Test-Path System.Management.Automation.Provider.ItemCmdletProvider.ItemExists を呼び出すコマンドレットでは、実行時に動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、Windows PowerShell項目プロバイダーが 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 動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、Windows PowerShell項目プロバイダーが 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 動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、Windows PowerShell項目プロバイダーで 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 動的に指定される追加のパラメーターが必要な場合があります。 これらの動的パラメーターを指定するには、Windows PowerShell項目プロバイダーが System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultActionDynamicParameters メソッドを実装する必要があります。 このメソッドは、指定されたパスにある項目の動的パラメーターを取得し、コマンドレット クラスまたは System.Management.Automation.RuntimeDefinedParameterDictionary オブジェクトのような解析属性を持つプロパティとフィールドを持つオブジェクトを返します。 Windows PowerShell ランタイムは、返されたオブジェクトを使用して、動的パラメーターをコマンドレットにInvoke-Item追加します。

この項目プロバイダーでは、このメソッドは実装されていません。 ただし、次のコードは、このメソッドの既定の実装です。

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

この項目プロバイダーは、Windows PowerShellによって定義されたパブリック オーバーライド メソッドによって使用されるいくつかのヘルパー メソッドとクラスを実装します。 これらのヘルパー メソッドとクラスのコードは、「 コード サンプル 」セクションに示されています。

NormalizePath メソッド

この項目プロバイダーは、パスの形式が一貫していることを確認するために NormalizePath ヘルパー メソッドを実装します。 指定された形式では、区切り記号として円記号 (\) が使用されます。

PathIsDrive メソッド

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

ChunkPath メソッド

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

GetTable メソッド

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

GetRow メソッド

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

DatabaseTableInfo クラス

この項目プロバイダーは、データベース内のデータ テーブル内の情報のコレクションを表す DatabaseTableInfo クラスを定義します。 このクラスは System.IO.Directoryinfo クラスに似ています。

サンプル項目プロバイダーは、データベース内のテーブルを定義するテーブル情報オブジェクトのコレクションを返す DatabaseTableInfo.GetTables メソッドを定義します。 このメソッドには、エントリが 0 の行としてデータベース エラーが表示されるように、try/catch ブロックが含まれています。

DatabaseRowInfo クラス

この項目プロバイダーは、データベースのテーブル内の行を表す DatabaseRowInfo ヘルパー クラスを定義します。 このクラスは System.IO.FileInfo クラスに似ています。

サンプル プロバイダーは、指定されたテーブルの行情報オブジェクトのコレクションを返す DatabaseRowInfo.GetRows メソッドを定義します。 このメソッドには、例外をトラップする try/catch ブロックが含まれています。 エラーが発生しても、行情報は表示されません。

コード サンプル

完全なサンプル コードについては、 AccessDbProviderSample03 コード サンプルを参照してください。

オブジェクトの種類と書式の定義

プロバイダーを記述するときは、既存のオブジェクトにメンバーを追加するか、新しいオブジェクトを定義することが必要な場合があります。 完了したら、Windows PowerShell使用してオブジェクトのメンバーを識別できる Types ファイルと、オブジェクトの表示方法を定義する Format ファイルを作成します。 詳細については、「 オブジェクトの種類と書式の拡張」を参照してください。

Windows PowerShell プロバイダーの構築

コマンドレット、プロバイダー、およびホスト アプリケーションを登録する方法に関するページを参照してください。

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

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

こちらもご覧ください