Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Toto téma popisuje, jak vytvořit poskytovatele Windows PowerShell, který umožňuje uživateli manipulovat s obsahem položek v datovém úložišti. V důsledku toho se poskytovatel, který dokáže manipulovat s obsahem položek, nazývá poskytovatel obsahu Windows PowerShell.
Poznámka:
Zdrojový soubor C# (AccessDBSampleProvider06.cs) tohoto poskytovatele si můžete stáhnout pomocí Microsoft Windows Software Development Kit pro Windows Vista a .NET Framework 3.0 Runtime Components. Pro návod ke stažení viz Jak nainstalovat Windows PowerShell a Stáhněte si Windows PowerShell SDK. Stažené zdrojové soubory jsou dostupné v adresáři <PowerShell Samples> . Pro více informací o dalších implementacích poskytovatelů Windows PowerShell viz Návrh vašeho poskytovatele Windows PowerShell.
Definujte třídu poskytovatele obsahu Windows PowerShell
Poskytovatel obsahu ve Windows PowerShell musí vytvořit .NET třídu, která podporuje rozhraní System.Management.Automation.Provider.IContentCmdletProvider . Zde je definice třídy poskytovatele položek popsaná v této sekci.
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : NavigationCmdletProvider, IContentCmdletProvider
Všimněte si, že v této definici třídy atribut System.Management.Automation.Provider.CmdletProviderAttribute obsahuje dva parametry. První parametr určuje uživatelsky přívětivé jméno poskytovatele, které používá Windows PowerShell. Druhý parametr specifikuje specifické schopnosti Windows PowerShell, které poskytovatel zpřístupňuje běhu Windows PowerShell během zpracování příkazů. Pro tohoto poskytovatele nejsou přidané specifické funkce Windows PowerShell.
Definujte funkčnost základní třídy
Jak je popsáno v knize Design Your Windows PowerShell Provider, třída System.Management.Automation.Provider.NavigationCmdletProvider pochází z několika dalších tříd, které nabízely různé funkce poskytovatelů. Poskytovatel obsahu ve Windows PowerShell tedy obvykle definuje veškerou funkcionalitu poskytovanou těmito třídami.
Pro více informací o tom, jak implementovat funkce pro přidání specifických inicializačních informací pro relaci a pro uvolnění zdrojů používaných poskytovatelem, viz Vytvoření základního poskytovatele Windows PowerShell. Většina poskytovatelů, včetně zde popsaného poskytovatele, však může použít výchozí implementaci této funkce, kterou poskytuje Windows PowerShell.
Pro přístup k datovému úložišti musí poskytovatel implementovat metody základní třídy System.Management.Automation.Provider.DriveCmdletProvider . Pro více informací o implementaci těchto metod viz Vytvoření poskytovatele disku Windows PowerShell.
Pro manipulaci s položkami datového úložiště, jako je získávání, nastavování a vyřizování položek, musí poskytovatel implementovat metody poskytované základní třídou System.Management.Automation.Provider.ItemCmdletProvider . Pro více informací o implementaci těchto metod viz Vytvoření poskytovatele položek Windows PowerShell.
Pro práci s vícevrstvými datovými úložišti musí poskytovatel implementovat metody poskytované základní třídou System.Management.Automation.Provider.ContainerCmdletProvider . Pro více informací o implementaci těchto metod viz Vytvoření Windows PowerShell Container Provider.
Pro podporu rekurzivních příkazů, vnořených kontejnerů a relativních cest musí poskytovatel implementovat základní třídu System.Management.Automation.Provider.NavigationCmdletProvider . Kromě toho může tento poskytovatel obsahu Windows PowerShell připojit rozhraní System.Management.Automation.Provider.IContentCmdletProvider k základní třídě System.Management.Automation.Provider.NavigationCmdletProvider , a proto musí implementovat metody poskytované touto třídou. Pro více informací viz implementace těchto metod viz Implementace navigace Windows PowerShell Provider.
Implementace čtečky obsahu
Pro čtení obsahu z položky musí poskytovatel implementovat třídu čtečky obsahu, která vychází ze System.Management.Automation.Provider.IContentReader. Čtečka obsahu tohoto poskytovatele umožňuje přístup k obsahu řádku v datové tabulce. Třída Content reader definuje metodu čtení , která získává data z uvedeného řádku a vrací seznam reprezentující tato data, metodu Seek , která přesouvá čtečku obsahu, metodu Close , která čtečku obsahu uzavírá, a metodu Dispose .
public class AccessDBContentReader : IContentReader
{
// A provider instance is required so as to get "content"
private AccessDBProvider provider;
private string path;
private long currentOffset;
internal AccessDBContentReader(string path, AccessDBProvider provider)
{
this.path = path;
this.provider = provider;
}
/// <summary>
/// Read the specified number of rows from the source.
/// </summary>
/// <param name="readCount">The number of items to
/// return.</param>
/// <returns>An array of elements read.</returns>
public IList Read(long readCount)
{
// Read the number of rows specified by readCount and increment
// offset
string tableName;
int rowNumber;
PathType type = provider.GetNamesFromPath(path, out tableName, out rowNumber);
Collection<DatabaseRowInfo> rows =
provider.GetRows(tableName);
Collection<DataRow> results = new Collection<DataRow>();
if (currentOffset < 0 || currentOffset >= rows.Count)
{
return null;
}
int rowsRead = 0;
while (rowsRead < readCount && currentOffset < rows.Count)
{
results.Add(rows[(int)currentOffset].Data);
rowsRead++;
currentOffset++;
}
return results;
} // Read
/// <summary>
/// Moves the content reader specified number of rows from the
/// origin
/// </summary>
/// <param name="offset">Number of rows to offset</param>
/// <param name="origin">Starting row from which to offset</param>
public void Seek(long offset, System.IO.SeekOrigin origin)
{
// get the number of rows in the table which will help in
// calculating current position
string tableName;
int rowNumber;
PathType type = provider.GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Invalid)
{
throw new ArgumentException("Path specified must represent a table or a row :" + path);
}
if (type == PathType.Table)
{
Collection<DatabaseRowInfo> rows = provider.GetRows(tableName);
int numRows = rows.Count;
if (offset > rows.Count)
{
throw new
ArgumentException(
"Offset cannot be greater than the number of rows available"
);
}
if (origin == System.IO.SeekOrigin.Begin)
{
// starting from Beginning with an index 0, the current offset
// has to be advanced to offset - 1
currentOffset = offset - 1;
}
else if (origin == System.IO.SeekOrigin.End)
{
// starting from the end which is numRows - 1, the current
// offset is so much less than numRows - 1
currentOffset = numRows - 1 - offset;
}
else
{
// calculate from the previous value of current offset
// advancing forward always
currentOffset += offset;
}
} // if (type...
else
{
// for row, the offset will always be set to 0
currentOffset = 0;
}
} // Seek
/// <summary>
/// Closes the content reader, so all members are reset
/// </summary>
public void Close()
{
Dispose();
} // Close
/// <summary>
/// Dispose any resources being used
/// </summary>
public void Dispose()
{
Seek(0, System.IO.SeekOrigin.Begin);
GC.SuppressFinalize(this);
} // Dispose
} // AccessDBContentReader
Implementace Content Writera
Pro napsání obsahu na položku musí poskytovatel implementovat třídu content writer odvozenou ze System.Management.Automation.Provider.IContentWriter. Třída content writer definuje metodu Write , která zapisuje zadaný obsah řádku, metodu Sekeen , která přesouvá content writera, metodu Close , která uzavírá content writera, a metodu Dispose .
public class AccessDBContentWriter : IContentWriter
{
// A provider instance is required so as to get "content"
private AccessDBProvider provider;
private string path;
private long currentOffset;
internal AccessDBContentWriter(string path, AccessDBProvider provider)
{
this.path = path;
this.provider = provider;
}
/// <summary>
/// Write the specified row contents in the source
/// </summary>
/// <param name="content"> The contents to be written to the source.
/// </param>
/// <returns>An array of elements which were successfully written to
/// the source</returns>
///
public IList Write(IList content)
{
if (content == null)
{
return null;
}
// Get the total number of rows currently available it will
// determine how much to overwrite and how much to append at
// the end
string tableName;
int rowNumber;
PathType type = provider.GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Table)
{
OdbcDataAdapter da = provider.GetAdapterForTable(tableName);
if (da == null)
{
return null;
}
DataSet ds = provider.GetDataSetForTable(da, tableName);
DataTable table = provider.GetDataTable(ds, tableName);
string[] colValues = (content[0] as string).Split(',');
// set the specified row
DataRow row = table.NewRow();
for (int i = 0; i < colValues.Length; i++)
{
if (!String.IsNullOrEmpty(colValues[i]))
{
row[i] = colValues[i];
}
}
//table.Rows.InsertAt(row, rowNumber);
// Update the table
table.Rows.Add(row);
da.Update(ds, tableName);
}
else
{
throw new InvalidOperationException("Operation not supported. Content can be added only for tables");
}
return null;
} // Write
/// <summary>
/// Moves the content reader specified number of rows from the
/// origin
/// </summary>
/// <param name="offset">Number of rows to offset</param>
/// <param name="origin">Starting row from which to offset</param>
public void Seek(long offset, System.IO.SeekOrigin origin)
{
// get the number of rows in the table which will help in
// calculating current position
string tableName;
int rowNumber;
PathType type = provider.GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Invalid)
{
throw new ArgumentException("Path specified should represent either a table or a row : " + path);
}
Collection<DatabaseRowInfo> rows =
provider.GetRows(tableName);
int numRows = rows.Count;
if (offset > rows.Count)
{
throw new
ArgumentException(
"Offset cannot be greater than the number of rows available"
);
}
if (origin == System.IO.SeekOrigin.Begin)
{
// starting from Beginning with an index 0, the current offset
// has to be advanced to offset - 1
currentOffset = offset - 1;
}
else if (origin == System.IO.SeekOrigin.End)
{
// starting from the end which is numRows - 1, the current
// offset is so much less than numRows - 1
currentOffset = numRows - 1 - offset;
}
else
{
// calculate from the previous value of current offset
// advancing forward always
currentOffset += offset;
}
} // Seek
/// <summary>
/// Closes the content reader, so all members are reset
/// </summary>
public void Close()
{
Dispose();
} // Close
/// <summary>
/// Dispose any resources being used
/// </summary>
public void Dispose()
{
Seek(0, System.IO.SeekOrigin.Begin);
GC.SuppressFinalize(this);
} // Dispose
} // AccessDBContentWriter
Získání čtečky obsahu
Pro získání obsahu z položky musí poskytovatel implementovat System.Management.Automation.Provider.IContentCmdletProvider.GetContentReader* pro podporu Get-Content cmdletu. Tato metoda vrací čtečku obsahu pro položku umístěnou na určené cestě. Objekt čtečky lze pak otevřít pro čtení obsahu.
Zde je implementace System.Management.Automation.Provider.IContentCmdletProvider.GetContentReader* pro tuto metodu pro tohoto poskytovatele.
public IContentReader GetContentReader(string path)
{
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Invalid)
{
ThrowTerminatingInvalidPathException(path);
}
else if (type == PathType.Row)
{
throw new InvalidOperationException("contents can be obtained only for tables");
}
return new AccessDBContentReader(path, this);
} // GetContentReader
public IContentReader GetContentReader(string path)
{
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Invalid)
{
ThrowTerminatingInvalidPathException(path);
}
else if (type == PathType.Row)
{
throw new InvalidOperationException("contents can be obtained only for tables");
}
return new AccessDBContentReader(path, this);
} // GetContentReader
Věci, na které je třeba pamatovat při implementaci GetContentReader
Následující podmínky se mohou vztahovat na implementaci System.Management.Automation.Provider.IContentCmdletProvider.GetContentReader*:
Při definování třídy poskytovatele může poskytovatel obsahu Windows PowerShell deklarovat schopnosti poskytovatele ExpandWildcards, Filter, Include nebo Exclude z výčtu System.Management.Automation.Provider.ProviderCapabilities . V těchto případech musí implementace metody System.Management.Automation.Provider.IContentCmdletProvider.GetContentReader* zajistit, že cesta předaná metodě splňuje požadavky specifikovaných schopností. K tomu by metoda měla přistupovat k příslušným vlastnostem, například k vlastnostim System.Management.Automation.Provider.CmdletProvider.Exclude* a System.Management.Automation.Provider.CmdletProvider.Include* .
Ve výchozím nastavení by přepisy této metody neměly čtečku načítat objekty, které jsou uživateli skryté, pokud vlastnost System.Management.Automation.Provider.CmdletProvider.Force* není nastavena na
true. Chyba by měla být zapsána, pokud cesta představuje položku skrytou před uživatelem a System.Management.Automation.Provider.CmdletProvider.Force* je nastavena nafalse.
Připojení dynamických parametrů k Get-Content Cmdletu
Cmdlet Get-Content může vyžadovat další parametry, které jsou dynamicky specifikovány za běhu. Pro poskytnutí těchto dynamických parametrů musí poskytovatel obsahu Windows PowerShell implementovat metodu System.Management.Automation.Provider.IContentCmdletProvider.GetContentReaderdynamicparameters* . Tato metoda získává dynamické parametry pro položku na indikované cestě a vrací objekt, který má vlastnosti a pole s atributy pro parsování podobnými třídě cmdlet nebo objektu System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell používá vrácený objekt k přidání parametrů do cmdletu.
Tento poskytovatel kontejnerů Windows PowerShell tuto metodu neimplementuje. Následující kód je však výchozí implementací této metody.
public object GetContentReaderDynamicParameters(string path)
{
return null;
}
public object GetContentReaderDynamicParameters(string path)
{
return null;
}
Získání autora obsahu
Pro napsání obsahu na položku musí poskytovatel implementovat System.Management.Automation.Provider.IContentCmdletProvider.GetContentWriter* pro podporu Set-Content a Add-Content cmdletů. Tato metoda vrací autora obsahu pro položku umístěnou na určené cestě.
Zde je implementace System.Management.Automation.Provider.IContentCmdletProvider.GetContentWriter* pro tuto metodu.
public IContentWriter GetContentWriter(string path)
{
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Invalid)
{
ThrowTerminatingInvalidPathException(path);
}
else if (type == PathType.Row)
{
throw new InvalidOperationException("contents can be added only to tables");
}
return new AccessDBContentWriter(path, this);
}
public IContentWriter GetContentWriter(string path)
{
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Invalid)
{
ThrowTerminatingInvalidPathException(path);
}
else if (type == PathType.Row)
{
throw new InvalidOperationException("contents can be added only to tables");
}
return new AccessDBContentWriter(path, this);
}
Na co si pamatovat při implementaci GetContentWriter
Následující podmínky se mohou vztahovat na vaši implementaci System.Management.Automation.Provider.IContentCmdletProvider.GetContentWriter*:
Při definování třídy poskytovatele může poskytovatel obsahu Windows PowerShell deklarovat schopnosti poskytovatele ExpandWildcards, Filter, Include nebo Exclude z výčtu System.Management.Automation.Provider.ProviderCapabilities . V těchto případech musí implementace metody System.Management.Automation.Provider.IContentCmdletProvider.GetContentWriter* zajistit, že cesta předávaná metodě splňuje požadavky specifikovaných schopností. K tomu by metoda měla přistupovat k příslušným vlastnostem, například k vlastnostim System.Management.Automation.Provider.CmdletProvider.Exclude* a System.Management.Automation.Provider.CmdletProvider.Include* .
Ve výchozím nastavení by přepisování této metody nemělo načítat zapisovače pro objekty, které jsou uživateli skryté, pokud vlastnost System.Management.Automation.Provider.CmdletProvider.Force* není nastavena na
true. Chyba by měla být zapsána, pokud cesta představuje položku skrytou před uživatelem a System.Management.Automation.Provider.CmdletProvider.Force* je nastavena nafalse.
Připojování dynamických parametrů k Add-Content a Set-Content cmdletům
Cmdlets Add-Content and Set-Content mohou vyžadovat další dynamické parametry, které se přidávají za běhu. Aby poskytovatel obsahu ve Windows PowerShell mohl tyto dynamické parametry zajistit, musí implementovat metodu System.Management.Automation.Provider.IContentCmdletProvider.GetContentWriterDynamicParameters* pro zpracování těchto parametrů. Tato metoda získává dynamické parametry pro položku na indikované cestě a vrací objekt, který má vlastnosti a pole s atributy pro parsování podobnými třídě cmdlet nebo objektu System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell používá vrácený objekt k přidání parametrů do cmdletů.
Tento poskytovatel kontejnerů Windows PowerShell tuto metodu neimplementuje. Následující kód je však výchozí implementací této metody.
public object GetContentWriterDynamicParameters(string path)
{
return null;
}
Clearingový obsah
Váš poskytovatel obsahu implementuje metodu System.Management.Automation.Provider.IContentCmdletProvider.ClearContent* na podporu Clear-Content tohoto cmdletu. Tato metoda odstraní obsah položky na určené cestě, ale položku ponechá nedotčenou.
Zde je implementace metody System.Management.Automation.Provider.IContentCmdletProvider.ClearContent* pro tohoto poskytovatele.
public void ClearContent(string path)
{
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type != PathType.Table)
{
WriteError(new ErrorRecord(
new InvalidOperationException("Operation not supported. Content can be cleared only for table"),
"NotValidRow", ErrorCategory.InvalidArgument,
path));
return;
}
OdbcDataAdapter da = GetAdapterForTable(tableName);
if (da == null)
{
return;
}
DataSet ds = GetDataSetForTable(da, tableName);
DataTable table = GetDataTable(ds, tableName);
// Clear contents at the specified location
for (int i = 0; i < table.Rows.Count; i++)
{
table.Rows[i].Delete();
}
if (ShouldProcess(path, "ClearContent"))
{
da.Update(ds, tableName);
}
} // ClearContent
Na co si pamatovat při implementaci ClearContent
Následující podmínky se mohou vztahovat na implementaci System.Management.Automation.Provider.IContentCmdletProvider.ClearContent*:
Při definování třídy poskytovatele může poskytovatel obsahu Windows PowerShell deklarovat schopnosti poskytovatele ExpandWildcards, Filter, Include nebo Exclude z výčtu System.Management.Automation.Provider.ProviderCapabilities . V těchto případech musí implementace metody System.Management.Automation.Provider.IContentCmdletProvider.ClearContent* zajistit, že cesta předávaná metodě splňuje požadavky specifikovaných schopností. K tomu by metoda měla přistupovat k příslušným vlastnostem, například k vlastnostim System.Management.Automation.Provider.CmdletProvider.Exclude* a System.Management.Automation.Provider.CmdletProvider.Include* .
Ve výchozím nastavení by přepisy této metody neměly vymazat obsah objektů, které jsou uživateli skryté, pokud vlastnost System.Management.Automation.Provider.CmdletProvider.Force* není nastavena na
true. Chyba by měla být zapsána, pokud cesta představuje položku skrytou před uživatelem a System.Management.Automation.Provider.CmdletProvider.Force* je nastavena nafalse.Vaše implementace metody System.Management.Automation.Provider.IContentCmdletProvider.ClearContent* by měla volat System.Management.Automation.Provider.CmdletProvider.ShouldProcess a ověřit její návratovou hodnotu před jakýmikoli změnami v datovém úložišti. Tato metoda se používá k potvrzení provedení operace při změně datového úložiště, například vymazání obsahu. Metoda System.Management.Automation.Provider.CmdletProvider.ShouldProcess odesílá uživateli název zdroje, který má být změněn, přičemž runtime Windows PowerShell zpracovává všechna nastavení příkazové řádky nebo preference proměnné při určování, co má být zobrazeno.
Po návratu
truevolání na System.Management.Automation.Provider.CmdletProvider.OughtProcess by měla metoda System.Management.Automation.Provider.IContentCmdletProvider.ClearContent* zavolat metodu System.Management.Automation.Provider.CmdletProvider.ShouldContinue. Tato metoda odesílá uživateli zprávu, která umožňuje zpětnou vazbu ověřit, zda by měla být operace pokračována. Volání na System.Management.Automation.Provider.CmdletProvider.ShouldContinue umožňuje další kontrolu potenciálně nebezpečných systémových úprav.
Připojení dynamických parametrů k Clear-Content Cmdletu
Cmdlet Clear-Content může vyžadovat další dynamické parametry, které se přidávají za běhu. Pro poskytnutí těchto dynamických parametrů musí poskytovatel obsahu Windows PowerShell implementovat metodu System.Management.Automation.Provider.IContentCmdletProvider.ClearContentDynamicParameters* pro zpracování těchto parametrů. Tato metoda získá parametry položky na uvedené cestě. Tato metoda získává dynamické parametry pro položku na indikované cestě a vrací objekt, který má vlastnosti a pole s atributy pro parsování podobnými třídě cmdlet nebo objektu System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell používá vrácený objekt k přidání parametrů do cmdletu.
Tento poskytovatel kontejnerů Windows PowerShell tuto metodu neimplementuje. Následující kód je však výchozí implementací této metody.
public object ClearContentDynamicParameters(string path)
{
return null;
}
public object ClearContentDynamicParameters(string path)
{
return null;
}
Ukázka kódu
Pro kompletní ukázkový kód viz AccessDbProviderSample06 Code Sample.
Definování typů objektů a formátování
Při psaní poskytovatele může být nutné přidávat členy k existujícím objektům nebo definovat nové objekty. Když je to hotové, musíte vytvořit soubor Types, který Windows PowerShell použije k identifikaci členů objektu, a formátový soubor, který definuje, jak je objekt zobrazen. Pro více informací viz Rozšíření typů objektů a formátování.
Vytvoření Windows PowerShell Provider
Podívejte se, jak registrovat cmdlety, poskytovatele a hostitelské aplikace.
Testování Windows PowerShell Provider
Když je váš poskytovatel Windows PowerShell registrován ve Windows PowerShell, můžete to otestovat spuštěním podporovaných cmdletů na příkazovém řádku. Například otestujte poskytovatele vzorkového obsahu.
Použijte Get-Content cmdlet k získání obsahu zadané položky v databázové tabulce na cestě určené parametrem Path . Parametr ReadCount určuje počet položek, které má definovaná čtečka obsahu číst (výchozí 1). S následujícím příkazem cmdlet načte dva řádky (položky) z tabulky a zobrazí jejich obsah. Všimněte si, že následující příklad výstupu používá fiktivní databázi Access.
Get-Content -Path mydb:\Customers -ReadCount 2
ID : 1
FirstName : Eric
LastName : Gruber
Email : ericgruber@fabrikam.com
Title : President
Company : Fabrikam
WorkPhone : (425) 555-0100
Address : 4567 Main Street
City : Buffalo
State : NY
Zip : 98052
Country : USA
ID : 2
FirstName : Eva
LastName : Corets
Email : evacorets@cohowinery.com
Title : Sales Representative
Company : Coho Winery
WorkPhone : (360) 555-0100
Address : 8910 Main Street
City : Cabmerlot
State : WA
Zip : 98089
Country : USA
Viz také
Vytváření poskytovatelů Windows PowerShell
Navrhněte svého poskytovatele Windows PowerShell
Rozšíření typů objektů a formátování
Implementace navigačního poskytovatele Windows PowerShell
Jak registrovat cmdlety, poskytovatele a hostitelské aplikace