本主題說明如何建立一個 Windows PowerShell 提供者,以操作資料儲存中的資料。 在此主題中,儲存中的資料元素被稱為資料儲存的「項目」。 因此,能夠操作儲存資料的提供者稱為 Windows PowerShell 項目提供者。
備註
你可以使用 Microsoft Windows 軟體開發套件(Windows Vista 及 .NET Framework 3.0 執行時元件)下載 C# 原始碼檔案AccessDBSampleProvider03.cs()。 如需下載說明,請參閱 《如何安裝 Windows PowerShell》及《Download the Windows PowerShell SDK》。
下載的原始碼檔案可在 PowerShell Samples 目錄中取得。 欲了解更多關於其他 Windows PowerShell 提供者實作的資訊,請參閱 「設計您的 Windows PowerShell 提供者」。
本主題中描述的 Windows PowerShell 項目提供者是從 Access 資料庫取得資料項目。 此時,「項目」要麼是 Access 資料庫中的一個資料表,要麼是資料表中的一個列。
定義 Windows PowerShell 項目提供者類別
Windows PowerShell 項目提供者必須定義一個 .NET 類別,該類別源自 System.Management.Automation.Provider.ItemCmdletProvider 基底類別。 以下是本節所述項目提供者的類別定義。
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ItemCmdletProvider
請注意,在這個類別定義中, System.Management.Automation.Provider.CmdletProviderAttribute 屬性包含兩個參數。 第一個參數指定了 Windows PowerShell 所使用的使用者友善提供者名稱。 第二個參數指定了 Windows PowerShell 在指令處理過程中,向 Windows PowerShell 執行時所暴露的能力。 此提供者未新增 Windows PowerShell 專屬功能。
定義基礎功能
如《 設計你的 Windows PowerShell 提供者》所述, System.Management.Automation.Provider.DriveCmdletProvider 類別源自其他提供不同提供者功能的類別。 因此,Windows PowerShell 項目提供者必須定義這些類別所提供的所有功能。
欲了解更多關於如何實作加入特定會話初始化資訊及釋放提供者所使用資源的功能,請參閱 「建立基本 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 方法,驗證傳送給它的路徑的語法與語意有效性。 此方法回傳 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 方法的實作。 請注意,此方法呼叫 PathIsDrive、 ChunkPath 和 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 實作:
- 在定義提供者類別時,Windows PowerShell 項目提供者可能會根據 System.Management.Automation.Provider.ProviderCapabilities 的列舉宣告提供者能力為
ExpandWildcards、FilterInclude、 或Exclude。 在這些情況下, System.Management.Automation.Provider.ItemCmdletProvider.ItemExists 方法的實作必須確保傳送給該方法的路徑符合指定能力的要求。 為此,方法應存取適當的屬性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 與 System.Management.Automation.Provider.CmdletProvider.Include 屬性。 - 此方法的實作應能處理任何可能讓使用者可見的項目存取權限。 例如,若使用者透過 FileSystem 提供者(由 Windows PowerShell 提供)對檔案有寫入權限,但無法讀取,該檔案仍然存在, System.Management.Automation.Provider.ItemCmdletProvider.ItemExists 回傳
true。 你的實作可能需要檢查父項目,看看子項目是否能被列舉。
將動態參數附加到 Test-Path 指令小子
有時呼叫 System.Management.Automation.Provider.ItemCmdletProvider.ItemExists 的 Test-Path cmdlet 需要在執行時動態指定額外參數。 為了提供這些動態參數,Windows PowerShell 項目提供者必須實作 System.Management.Automation.Provider.ItemCmdletProvider.ItemExistsDynamicParameters 方法。 此方法會取得指定路徑項目的動態參數,並回傳一個具有屬性與欄位的物件,解析屬性類似於 cmdlet 類別或 System.Management.Automation.RuntimeDefinedParameterDictionary 物件。 Windows PowerShell 執行時會使用回傳的物件來將參數加入 Test-Path cmdlet。
這個 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 的實作:
在定義提供者類別時,Windows PowerShell 項目提供者可能會根據 System.Management.Automation.Provider.ProviderCapabilities 的列舉宣告提供者能力為
ExpandWildcards、FilterInclude、 或Exclude。 在這些情況下, System.Management.Automation.Provider.ItemCmdletProvider.GetItem 的實作必須確保傳遞給方法的路徑符合這些要求。 為此,方法應存取適當的屬性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 與 System.Management.Automation.Provider.CmdletProvider.Include 屬性。預設情況下,除非將 System.Management.Automation.Provider.CmdletProvider.Force 屬性設
true為 。 例如,System.Management.Automation.Provider.ItemCmdletProvider.GetItem 方法在嘗試呼叫隱藏或系統檔案前,會檢查 System.Management.Automation.Provider.CmdletProvider.Force 屬性。
將動態參數附加到 Get-Item 指令小子
有時 Get-Item cmdlet 需要額外參數,這些參數會在執行時動態指定。 為了提供這些動態參數,Windows PowerShell 項目提供者必須實作 System.Management.Automation.Provider.ItemCmdletProvider.GetItemDynamicParameters 方法。 此方法會取得指定路徑項目的動態參數,並回傳一個具有屬性與欄位的物件,解析屬性類似於 cmdlet 類別或 System.Management.Automation.RuntimeDefinedParameterDictionary 物件。 Windows PowerShell 執行時會使用回傳的物件來將參數加入 Get-Item cmdlet。
該提供者並未實作此方法。 然而,以下程式碼是此方法的預設實作。
設置物品
要設定項目,Windows PowerShell 項目提供者必須覆寫 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法,以支援從該 Set-Item 指令執行命令的呼叫。 此方法設定該項目在指定路徑上的值。
此提供者不提供 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法的覆寫。 不過,以下是此方法的預設實作。
實作 SetItem 需要注意的事項
以下條件可能適用於您的 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 實作:
在定義提供者類別時,Windows PowerShell 項目提供者可能會根據 System.Management.Automation.Provider.ProviderCapabilities 的列舉宣告提供者能力為
ExpandWildcards、FilterInclude、 或Exclude。 在這些情況下, System.Management.Automation.Provider.ItemCmdletProvider.SetItem 的實作必須確保傳遞給方法的路徑符合這些要求。 為此,方法應存取適當的屬性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 與 System.Management.Automation.Provider.CmdletProvider.Include 屬性。預設情況下,除非 System.Management.Automation.Provider.CmdletProvider.Force 屬性設
true為 ,否則此方法的覆寫不應設定或寫入對使用者隱藏的物件。 如果路徑代表隱藏項目且 System.Management.Automation.Provider.CmdletProvider.Force 設定為false。你實作的 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法,應該在對資料庫做任何變更前,先呼叫 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.ItemCmdletProvider.SetItem 方法應呼叫 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法。 此方法會向使用者發送訊息,以允許回饋以確認操作是否應繼續。 呼叫 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 可額外檢查潛在危險的系統修改。
取得 SetItem 的動態參數
有時 Set-Item cmdlet 需要額外參數,這些參數會在執行時動態指定。 為了提供這些動態參數,Windows PowerShell 項目提供者必須實作 System.Management.Automation.Provider.ItemCmdletProvider.SetItemDynamicParameters 方法。 此方法會取得指定路徑項目的動態參數,並回傳一個具有屬性與欄位的物件,解析屬性類似於 cmdlet 類別或 System.Management.Automation.RuntimeDefinedParameterDictionary 物件。 Windows PowerShell 執行時會使用回傳的物件來將參數加入 Set-Item cmdlet。
該提供者並未實作此方法。 然而,以下程式碼是此方法的預設實作。
清除物品
要清除項目時,Windows PowerShell 項目提供者實作了 System.Management.Automation.Provider.ItemCmdletProvider.ClearItem 方法來支援從該 Clear-Item 指令長呼叫。 此方法會抹除指定路徑上的資料項目。
該提供者並未實作此方法。 然而,以下程式碼是此方法的預設實作。
實施 ClearItem 時需要注意的事項
以下條件可能適用於 System.Management.Automation.Provider.ItemCmdletProvider.ClearItem 的實作:
在定義提供者類別時,Windows PowerShell 項目提供者可能會根據 System.Management.Automation.Provider.ProviderCapabilities 的列舉宣告提供者能力為
ExpandWildcards、FilterInclude、 或Exclude。 在這些情況下, System.Management.Automation.Provider.ItemCmdletProvider.ClearItem 的實作必須確保傳遞給方法的路徑符合這些要求。 為此,方法應存取適當的屬性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 與 System.Management.Automation.Provider.CmdletProvider.Include 屬性。預設情況下,除非 System.Management.Automation.Provider.CmdletProvider.Force 屬性設
true為 ,否則此方法的覆寫不應設定或寫入對使用者隱藏的物件。 如果路徑代表對使用者隱藏的項目,且 System.Management.Automation.Provider.CmdletProvider.Force 設定為false。你實作的 System.Management.Automation.Provider.ItemCmdletProvider.SetItem 方法,應該在對資料庫做任何變更前,先呼叫 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.ItemCmdletProvider.SetItem 方法應呼叫 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法。 此方法會向使用者發送訊息,以允許回饋以確認操作是否應繼續。 呼叫 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 可額外檢查潛在危險的系統修改。
取得 ClearItem 的動態參數
有時 Clear-Item cmdlet 需要額外參數,這些參數會在執行時動態指定。 為了提供這些動態參數,Windows PowerShell 項目提供者必須實作 System.Management.Automation.Provider.ItemCmdletProvider.ClearItemDynamicParameters 方法。 此方法會取得指定路徑項目的動態參數,並回傳一個具有屬性與欄位的物件,解析屬性類似於 cmdlet 類別或 System.Management.Automation.RuntimeDefinedParameterDictionary 物件。 Windows PowerShell 執行時會使用回傳的物件來將參數加入 Clear-Item cmdlet。
本項目提供者未實作此方法。 然而,以下程式碼是此方法的預設實作。
執行物品的預設動作
Windows PowerShell 項目提供者可實作 System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction 方法,以支援從 cmdlet 呼叫 Invoke-Item ,允許提供者在指定路徑對項目執行預設動作。 例如,FileSystem 提供者可能會使用此方法呼叫特定項目的 ShellExecute 。
該提供者並未實作此方法。 然而,以下程式碼是此方法的預設實作。
關於實作 InvokeDefaultAction 需要注意的事項
以下條件可能適用於 System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction 的實作:
在定義提供者類別時,Windows PowerShell 項目提供者可能會根據 System.Management.Automation.Provider.ProviderCapabilities 的列舉宣告提供者能力為
ExpandWildcards、FilterInclude、 或Exclude。 在這些情況下, System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction 的實作必須確保傳遞給方法的路徑符合這些要求。 為此,方法應存取適當的屬性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude 與 System.Management.Automation.Provider.CmdletProvider.Include 屬性。預設情況下,除非 System.Management.Automation.Provider.CmdletProvider.Force 屬性設
true為 。 如果路徑代表對使用者隱藏的項目,且 System.Management.Automation.Provider.CmdletProvider.Force 設定為false。
取得 InvokeDefaultAction 的動態參數
有時 Invoke-Item cmdlet 需要額外參數,這些參數會在執行時動態指定。 為了提供這些動態參數,Windows PowerShell 項目提供者必須實作 System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultActionDynamicParameters(InvokeDefaultActionDynamicParameters )方法。 此方法會取得指定路徑項目的動態參數,並回傳一個具有屬性與欄位的物件,解析屬性類似於 cmdlet 類別或 System.Management.Automation.RuntimeDefinedParameterDictionary 物件。 Windows PowerShell 執行時會利用回傳的物件,將動態參數加入 Invoke-Item cmdlet。
本項目提供者未實作此方法。 然而,以下程式碼是此方法的預設實作。
實作輔助方法與類別
此項目提供者實作了多個輔助方法與類別,這些方法由 Windows PowerShell 定義的公開覆寫方法所使用。 這些輔助方法與類別的程式碼可見於 程式碼範例 章節。
NormalizePath 方法
此項目提供者實作 NormalizePath 輔助方法,確保路徑格式一致。 所指定的格式使用反斜線(\)作為分隔符。
PathIsDrive 方法
這個項目提供者實作了 PathIsDrive 輔助工具的方法,用來判斷指定的路徑是否真的是磁碟機名稱。
區塊路徑方法
此項目提供者實作一個 ChunkPath 輔助方法,將指定路徑拆分,讓提供者能識別其個別元素。 它會回傳一個由路徑元素組成的陣列。
GetTable 方法
此項目提供者實作了 GetTables 輔助方法,回傳一個 DatabaseTableInfo 物件,代表呼叫中指定的資料表資訊。
GetRow 方法
System.Management.Automation.Provider.ItemCmdletProvider.GetItem 方法呼叫 GetRows 輔助工具。 此輔助方法會取得一個 DatabaseRowInfo 物件,代表表格中指定列的資訊。
DatabaseTableInfo 類別
此項目提供者定義了一個 DatabaseTableInfo 類別,代表資料庫資料表中的一組資訊。 此類別與 System.IO.Directoryinfo 類別相似。
範例項目提供者定義了一個 DatabaseTableInfo.GetTables 方法,該方法回傳一組定義資料庫中資料表的資訊物件。 此方法包含嘗試/捕捉區塊,確保任何資料庫錯誤都以零條目列顯示。
DatabaseRowInfo 類別
此項目提供者定義了 DatabaseRowInfo 輔助類別,代表資料庫資料表中的一列。 此類別與 System.IO.FileInfo 類別相似。
範例提供者定義了一個 DatabaseRowInfo.GetRows 方法,用以回傳指定資料表的一組列資訊物件。 此方法包含嘗試/接球區塊以捕捉例外。 任何錯誤都會導致無列資訊。
程式碼範例
完整範例程式碼請參見 AccessDbProviderSample03 程式碼範例。
定義物件類型與格式
在撰寫提供者時,可能需要為現有物件新增成員或定義新的物件。 完成後,建立一個 Types 檔案,讓 Windows PowerShell 用來辨識物件成員,並建立一個定義物件顯示方式的 Format 檔案。 欲了解更多資訊,請參閱 擴展物件類型與格式化。
建置 Windows PowerShell 提供者
請參閱 如何註冊指令長、提供者及主機應用程式。
測試 Windows PowerShell 提供者
當這個 Windows PowerShell 項目提供者註冊在 Windows PowerShell 時,你只能測試該提供者的基本功能和磁碟功能。 要測試項目操作,你也必須實作《 Implementing a Container Windows PowerShell Provider》中描述的容器功能。