アイテム プロバイダーを記述する
このトピックでは、データ ストア内の項目にアクセスして操作する Windows PowerShell プロバイダーのメソッドを実装する方法について説明します。 項目にアクセスするには、プロバイダーが System.Management.Automation.Provider.Itemcmdletprovider クラスから派生している必要 があります。
このトピックの例のプロバイダーでは、Access データベースをデータ ストアとして使用します。 データベースとの対話に使用されるヘルパー メソッドとクラスがいくつかあります。 ヘルパー メソッドを含む完全なサンプルについては 、「AccessDBProviderSample03」を参照してください。
プロバイダーの詳細については、「Windows PowerShellプロバイダーの概要」Windows PowerShell参照してください。
項目メソッドの実装
System.Management.Automation.Provider.Itemcmdletproviderクラスは、データ ストア内の項目にアクセスして操作するために使用できるいくつかのメソッドを公開します。 これらのメソッドの完全な一覧については 、「ItemCmdletProvider メソッド」を参照してください。 この例では、これらのメソッドの 4 つを実装します。 System.Management.Automation.Provider.Itemcmdletprovider.Getitem* は 、指定されたパスにある項目を取得します。 System.Management.Automation.Provider.Itemcmdletprovider.Setitem* は 、指定された項目の値を設定します。 System.Management.Automation.Provider.Itemcmdletprovider.Itemexists* は、指定されたパスに項目が存在するかどうかを確認します。 System.Management.Automation.Provider.Itemcmdletprovider.Isvalidpath* は、パスがデータ ストア内の場所にマップされるのを確認します。
注意
このトピックは、「プロバイダーのクイック スタート」のWindows PowerShell基づいています。 このトピックでは、プロバイダー プロジェクトを設定する方法の基本、またはドライブを作成および削除する System.Management.Automation.Provider.Drivecmdletprovider クラスから継承されたメソッドを実装する方法については説明します。
プロバイダー クラスの宣言
System.Management.Automation.Provider.Itemcmdletproviderクラスから派生するプロバイダーを宣言し、System.Management.Automation.Provider.Cmdletproviderattributeで装飾します。
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ItemCmdletProvider
{
}
GetItem の実装
System.Management.Automation.Provider.Itemcmdletprovider.Getitem*は、ユーザーがプロバイダーでMicrosoft.PowerShell.Commands.GetItemCommandコマンドレットを呼び出す際に、PowerShell エンジンによって呼び出されます。 メソッドは、指定されたパスにある項目を返します。 Access データベースの例では、 メソッドは、項目がドライブ自体か、データベース内のテーブルか、データベース内の行かを確認します。 メソッドは 、System.Management.Automation.Provider.Cmdletprovider.Writeitemobject* メソッドを呼び出して、PowerShell エンジンに項目を送信します。
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);
}
}
SetItem の実装
System.Management.Automation.Provider.Itemcmdletprovider.Setitem*メソッドは、ユーザーがMicrosoft.PowerShell.Commands.SetItemCommandコマンドレットを呼び出す際に、PowerShell エンジンによって呼び出されます。 指定したパスにある項目の値を設定します。
Access データベースの例では、その項目が行である場合にのみ項目の値を設定すると意味があります。そのため、 メソッドは、項目が行ではない場合に NotSupportedException をスローします。
protected override void SetItem(string path, object values)
{
// Get type, table name and row number from the path specified
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type != PathType.Row)
{
WriteError(new ErrorRecord(new NotSupportedException(
"SetNotSupported"), "",
ErrorCategory.InvalidOperation, path));
return;
}
// Get in-memory representation of table
OdbcDataAdapter da = GetAdapterForTable(tableName);
if (da == null)
{
return;
}
DataSet ds = GetDataSetForTable(da, tableName);
DataTable table = GetDataTable(ds, tableName);
if (rowNumber >= table.Rows.Count)
{
// The specified row number has to be available. If not
// NewItem has to be used to add a new row
throw new ArgumentException("Row specified is not available");
} // if (rowNum...
string[] colValues = (values as string).Split(',');
// set the specified row
DataRow row = table.Rows[rowNumber];
for (int i = 0; i < colValues.Length; i++)
{
row[i] = colValues[i];
}
// Update the table
if (ShouldProcess(path, "SetItem"))
{
da.Update(ds, tableName);
}
}
ItemExists の実装
System.Management.Automation.Provider.Itemcmdletprovider.Itemexists*メソッドは、ユーザーがMicrosoft.PowerShell.Commands.TestPathCommandコマンドレットを呼び出す際に、PowerShell エンジンによって呼び出されます。 メソッドは、指定したパスに項目が含されているかどうかを判断します。 項目が存在する場合、メソッドは System.Management.Automation.Provider.Cmdletprovider.Writeitemobject*を呼び出して PowerShell エンジンに戻します。
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;
}
IsValidPath の実装
System.Management.Automation.Provider.Itemcmdletprovider.Isvalidpath*メソッドは、指定されたパスが現在のプロバイダーに対して構文的に有効かどうかを確認します。 パスに項目が存在するかどうかは確認されません。
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;
}
次のステップ
一般的な実際のプロバイダーは、他の項目を含む項目をサポートし、ドライブ内のあるパスから別のパスに項目を移動することができます。 コンテナーをサポートするプロバイダーの例については、「コンテナー プロバイダーの作成 」を参照してください。 項目の移動をサポートするプロバイダーの例については、「ナビゲーション プロバイダーの作成 」を参照してください。
参照
フィードバック
フィードバックの送信と表示