本主題描述如何建立可巡覽數據存放區的 Windows PowerShell 流覽提供者。 這種類型的提供者支援遞歸命令、巢狀容器和相對路徑。
備註
您可以使用適用於 Windows Vista 和 .NET Framework 3.0 執行時間元件的 Microsoft Windows 軟體開發工具包,下載此提供者的 C# 原始程式檔 (AccessDBSampleProvider05.cs)。 如需下載指示,請參閱 如何安裝 Windows PowerShell 和下載 Windows PowerShell SDK。 下載的來源檔案可在 <PowerShell 範例> 目錄中取得。 如需其他 Windows PowerShell 提供者實作的詳細資訊,請參閱 設計 Windows PowerShell 提供者。
此處所述的提供者可讓使用者將 Access 資料庫當做磁碟驅動器來處理,讓使用者可以巡覽至資料庫中的數據表。 建立您自己的流覽提供者時,您可以實作方法,讓流覽所需的磁碟驅動器限定路徑、正規化相對路徑、移動數據存放區的專案,以及取得子名稱的方法、取得專案的父路徑,以及測試以識別專案是否為容器。
謹慎
請注意,此設計假設資料庫具有名稱標識碼的欄位,且字段的類型為 LongInteger。
定義 Windows PowerShell 提供者
Windows PowerShell 導覽提供者必須建立衍生自 System.Management.Automation.Provider.NavigationCmdletProvider 基類的 .NET 類別。 以下是本節中所述之導覽提供者的類別定義。
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : NavigationCmdletProvider
請注意,在此提供者中,System.Management.Automation.Provider.CmdletProviderAttribute 屬性包含兩個參數。 第一個參數會指定 Windows PowerShell 所使用提供者的用戶易記名稱。 第二個參數會指定提供者在命令處理期間公開給 Windows PowerShell 運行時間的 Windows PowerShell 特定功能。 針對此提供者,沒有新增的 Windows PowerShell 特定功能。
定義基底功能
如 設計 PS 提供者中所述,System.Management.Automation.Provider.NavigationCmdletProvider 基類衍生自提供不同提供者功能的數個其他類別。 因此,Windows PowerShell 流覽提供者必須定義這些類別所提供的所有功能。
若要實作功能來新增工作階段特定的初始化資訊,以及釋放提供者所使用的資源,請參閱 建立基本 PS 提供者。 不過,大部分提供者(包括此處所述的提供者)都可以使用 Windows PowerShell 所提供的此功能的默認實作。
若要透過 Windows PowerShell 磁碟驅動器存取資料存放區,您必須實作 System.Management.Automation.Provider.DriveCmdletProvider 基類的方法。 如需實作這些方法的詳細資訊,請參閱 建立 Windows PowerShell 磁碟驅動器提供者。
若要作數據存放區的專案,例如取得、設定和清除專案,提供者必須實作 System.Management.Automation.Provider.ItemCmdletProvider 基類所提供的方法。 如需實作這些方法的詳細資訊,請參閱 建立 Windows PowerShell 專案提供者。
若要取得數據存放區子專案或其名稱,以及建立、複製、重新命名和移除專案的方法,您必須實作 System.Management.Automation.Provider.ContainerCmdletProvider 基類所提供的方法。 如需實作這些方法的詳細資訊,請參閱 建立 Windows PowerShell 容器提供者。
建立 Windows PowerShell 路徑
Windows PowerShell 流覽提供者會使用提供者內部的 Windows PowerShell 路徑來巡覽數據存放區的專案。 若要建立提供者內部路徑,提供者必須實作 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 方法,以支援從 Combine-Path Cmdlet 呼叫。 這個方法會使用父路徑和子路徑之間的提供者特定路徑分隔符,將父路徑和子路徑合併成提供者內部路徑。
默認實作會採用路徑“/” 或 “\” 做為路徑分隔符、將路徑分隔符正規化為 “\”、結合父系和子路徑部分與分隔符之間的分隔符,然後傳回包含合併路徑的字元串。
此流覽提供者不會實作這個方法。 不過,下列程式代碼是 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 方法的默認實作。
實作MakePath的注意事項
下列條件可能適用於您實作 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath*:
您實作 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 方法不應驗證路徑為提供者命名空間中合法的完整路徑。 請注意,每個參數只能代表路徑的一部分,而且合併的元件可能不會產生完整路徑。 例如,FileSystem 提供者的 System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* 方法可能會在
parent
參數中收到 “windows\system32”,並在child
參數中收到 “abc.dll”。 方法會將這些值與 “\” 分隔符聯結,並傳回 “windows\system32\abc.dll”,這不是完整的文件系統路徑。這很重要
呼叫 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* 方法應該在路徑分隔符上以語匯方式分割路徑。 如果提供的路徑不包含路徑分隔符,則方法應該會傳回未修改的路徑。
這很重要
呼叫這個方法中提供的路徑可能包含提供者命名空間中不合法的字元。 這些字元最有可能用於通配符擴充或正則表示式比對,而且這個方法的實作不應該移除它們。
判斷專案是否為容器
巡覽提供者可以實作 System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* 方法來判斷指定的路徑是否表示容器。 如果路徑代表容器,則會傳回 true,否則傳回 false。 使用者需要此方法,才能針對提供的路徑使用 Test-Path
Cmdlet。
下列程式代碼顯示範例導覽提供者中的 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
Cmdlet,您的導覽提供者會實作 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
,否則此方法的覆寫不應該將物件移至現有的物件上。 例如,除非 System.Management.Automation.Provider.CmdletProvider.Force* 属性設定為 true
,否則 FileSystem 提供者不會透過現有的 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.ShouldContinue 方法。 這個方法會將訊息傳送給使用者,以允許意見反應指出是否應該繼續作業。 您的提供者應該呼叫 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 做為額外的檢查,以檢查潛在的危險系統修改。
將動態參數附加至 Move-Item Cmdlet
有時候,Move-Item
Cmdlet 需要運行時間動態提供的其他參數。 若要提供這些動態參數,巡覽提供者必須實作 System.Management.Automation.Provider.NavigationCmdletProvider.MoveItemDynamicParameters* 方法,以從指定路徑的專案取得必要的參數值,並傳回具有類似 Cmdlet 類別或 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 程式代碼範例。
定義物件類型和格式設定
提供者可以將成員新增至現有物件或定義新物件。 如需詳細資訊,請參閱擴充物件類型和格式設定。
建置 Windows PowerShell 提供者
如需詳細資訊,請參閱 如何註冊 Cmdlet、提供者和主應用程式。
測試 Windows PowerShell 提供者
當您的 Windows PowerShell 提供者已向 Windows PowerShell 註冊時,您可以在命令行上執行支援的 Cmdlet 來測試它,包括衍生所提供的 Cmdlet。 此範例會測試範例導覽提供者。
執行新的殼層,並使用
Set-Location
Cmdlet 來設定路徑以指出 Access 資料庫。Set-Location mydb:
現在執行
Get-ChildItem
Cmdlet 來擷取資料庫項目的清單,也就是可用的資料庫數據表。 對於每個數據表,此 Cmdlet 也會擷取數據表數據列的數目。Get-ChildItem | Format-Table RowCount, Name -AutoSize
RowCount 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
Cmdlet 來設定 Employees 數據表的位置。Set-Location Employees
現在讓我們使用
Get-Location
Cmdlet 來擷取 Employees 數據表的路徑。Get-Location
Path ---- mydb:\Employees
現在,使用管線傳送至
Format-Table
Cmdlet 的Get-ChildItem
Cmdlet。 這組 Cmdlet 會擷取 Employees 數據表的專案,也就是數據表數據列。 它們的格式是由Format-Table
Cmdlet 所指定。Get-ChildItem | Format-Table RowNumber, PSIsContainer, Data -AutoSize
RowNumber 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
Cmdlet 來擷取 Employees 資料表第 0 列的專案。Get-Item 0
PSPath : 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 : 0
再次使用
Get-Item
Cmdlet 來擷取數據列 0 中項目的員工數據。(Get-Item 0).Data
EmployeeID : 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