Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
В этой теме описывается, как создать провайдера Windows PowerShell, который может работать с многоуровневыми хранилищами данных. Для такого типа хранилища хранилища верхний уровень хранилища содержит корневые элементы, а каждый следующий уровень называется узлом дочерних элементов. Позволяя пользователю работать с этими дочерними узлами, он может взаимодействовать иерархически через хранилище данных.
Провайдеры, способные работать с многоуровневыми хранилищами данных, называются провайдерами контейнеров Windows PowerShell. Однако имейте в виду, что провайдер контейнеров Windows PowerShell можно использовать только при наличии одного контейнера (без вложенных контейнеров) с элементами. Если есть вложенные контейнеры, то необходимо реализовать навигационного провайдера Windows PowerShell. Для получения дополнительной информации о внедрении навигационного провайдера Windows PowerShell см. раздел «Создание провайдера навигации Windows PowerShell».
Замечание
Вы можете скачать исходный файл на C# (AccessDBSampleProvider04.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, описанный здесь, определяет базу данных как единый контейнер, при этом таблицы и строки базы определяются как элементы контейнера.
Caution
Имейте в виду, что эта конструкция предполагает наличие базы данных с полем с идентификатором имени, и тип поля — LongInwhole число.
Определение класса провайдера контейнера Windows PowerShell
Провайдер контейнера Windows PowerShell должен определить класс .NET, который происходит из базового класса System.Management.Automation.Provider.ContainerCmdletProvider . Вот определение класса для провайдера контейнеров Windows PowerShell, описанного в этом разделе.
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ContainerCmdletProvider
Обратите внимание, что в этом определении класса атрибут System.Management.Automation.Provider.CmdletProviderAttribute включает два параметра. Первый параметр задаёт удобное для пользователя имя провайдера, используемое Windows PowerShell. Второй параметр определяет специфические для Windows PowerShell возможности, которые провайдер открывает в процессе выполнения Windows PowerShell во время обработки команд. Для этого провайдера нет добавленных специфических возможностей Windows PowerShell.
Определение базовой функциональности
Как описано в статье «Проектирование вашего Windows PowerShell Provider», класс System.Management.Automation.Provider.ContainerCmdletProvider происходит из нескольких других классов, предоставлявших разные функциональности провайдеров. Таким образом, поставщик контейнеров Windows PowerShell должен определить все функции, предоставляемые этими классами.
Чтобы реализовать функционал добавления информации о инициализации, специфичной для сессии, и для выпуска ресурсов, используемых провайдером, см. раздел «Создание базового провайдера Windows PowerShell». Однако большинство провайдеров (включая описанного здесь провайдера) могут использовать стандартную реализацию этой функции, предоставляемую Windows PowerShell.
Чтобы получить доступ к хранилищу данных, провайдер должен реализовать методы базового класса System.Management.Automation.Provider.DriveCmdletProvider . Для получения дополнительной информации о внедрении этих методов см. раздел «Создание провайдера дисков Windows PowerShell».
Для обработки элементов хранилища данных, таких как получение, установка и очистка элементов, провайдер должен реализовать методы, предоставляемые базовым классом System.Management.Automation.Provider.ItemCmdletProvider . Для получения дополнительной информации о реализации этих методов см. раздел «Создание поставщика элементов Windows PowerShell».
Извлечение дочерних предметов
Чтобы получить дочерний элемент, провайдер контейнера Windows PowerShell должен переопределить метод System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* для поддержки вызовов из Get-ChildItem cmdlet. Этот метод извлекает дочерние элементы из хранилища данных и записывает их в конвейер как объекты. Если recurse параметр cmdlet указан, метод получает все потомки независимо от их уровня. Если recurse параметр не указан, метод извлекает только один уровень дочерних элементов.
Вот реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* для этого провайдера. Обратите внимание, что этот метод извлекает дочерние элементы во всех таблицах базы данных, когда путь указывает на базу данных доступа, и извлекает дочерние элементы из строк этой таблицы, если путь указывает на таблицу данных.
protected override void GetChildItems(string path, bool recurse)
{
// If path represented is a drive then the children in the path are
// tables. Hence all tables in the drive represented will have to be
// returned
if (PathIsDrive(path))
{
foreach (DatabaseTableInfo table in GetTables())
{
WriteItemObject(table, path, true);
// if the specified item exists and recurse has been set then
// all child items within it have to be obtained as well
if (ItemExists(path) && recurse)
{
GetChildItems(path + pathSeparator + table.Name, recurse);
}
} // foreach (DatabaseTableInfo...
} // if (PathIsDrive...
else
{
// Get the table name, row number and type of path from the
// path specified
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Table)
{
// Obtain all the rows within the table
foreach (DatabaseRowInfo row in GetRows(tableName))
{
WriteItemObject(row, path + pathSeparator + row.RowNumber,
false);
} // foreach (DatabaseRowInfo...
}
else if (type == PathType.Row)
{
// In this case the user has directly specified a row, hence
// just give that particular row
DatabaseRowInfo row = GetRow(tableName, rowNumber);
WriteItemObject(row, path + pathSeparator + row.RowNumber,
false);
}
else
{
// In this case, the path specified is not valid
ThrowTerminatingInvalidPathException(path);
}
} // else
} // GetChildItems
Что стоит помнить о внедрении GetChildItems
К вашей реализации System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* могут применяться следующие условия:
При определении класса провайдера провайдер контейнеров Windows PowerShell может объявить возможности провайдера ExpandWildcards, Filter, Include или Exclude из перечисления System.Management.Automation.Provider.ProviderCapabilities . В таких случаях реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* должна гарантировать, что путь, переданный методу, соответствует требованиям указанных возможностей. Для этого метод должен получить доступ к соответствующим свойствам, например, к свойствам System.Management.Automation.Provider.CmdletProvider.Exclude* и свойствам System.Management.Automation.Provider.CmdletProvider.Include* .
Реализация этого метода должна учитывать любой доступ к предмету, который может сделать его видимым для пользователя. Например, если пользователь имеет доступ к записи файла через провайдера FileSystem (предоставленного Windows PowerShell), но нет доступа к чтению, файл всё равно существует, и System.Management.Automation.Provider.ItemCmdletProvider.ItemExists* возвращает
true. Ваша реализация может потребовать проверки родительского элемента, чтобы узнать, можно ли его перечислить.При написании нескольких элементов метод System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* может занять некоторое время. Вы можете спроектировать своего провайдера так, чтобы он писал элементы с помощью метода System.Management.Automation.Provider.CmdletProvider.WriteItemObject* по одному за раз. Использование этой техники позволит пользователю отображать элементы в потоке.
Ваша реализация System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* отвечает за предотвращение бесконечной рекурсии при наличии круговых связей и тому подобного. Должно быть введено соответствующее исключение, отражающее такое условие.
Прикрепление динамических параметров к командоустройству Get-ChildItem
Иногда Get-ChildItem cmdlet, вызывающий System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* , требует дополнительных параметров, которые динамически задаются во время выполнения. Для предоставления этих динамических параметров провайдер контейнеров Windows PowerShell должен реализовать метод System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItemsDynamicParameters* . Этот метод извлекает динамические параметры для элемента по указанному пути и возвращает объект с свойствами и полями с атрибутами разбора, похожими на класс cmdlet или объект System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell использует возвращённый объект для добавления параметров в Get-ChildItem cmdlet.
Этот провайдер контейнеров Windows PowerShell не реализует этот метод. Однако следующий код является стандартной реализацией этого метода.
Получение имён дочерних элементов
Чтобы получить имена дочерних элементов, провайдер контейнера Windows PowerShell должен переопределить метод System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* для поддержки вызовов из Get-ChildItem cmdlet при указании его Name параметра. Этот метод получает имена дочерних элементов для указанного пути или названия дочерних элементов для всех контейнеров, если returnAllContainers параметр cmdlet указан. Имя для ребёнка — это листовая часть дорожки. Например, дочернее имя пути C:\windows\system32\abc.dll — «abc.dll». Дочернее имя каталога C:\windows\system32 — «system32».
Вот реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* для этого провайдера. Обратите внимание, что метод получает имена таблиц, если указанный путь указывает на базу данных доступа (диск), а также номера строк, если путь указывает на таблицу.
protected override void GetChildNames(string path,
ReturnContainers returnContainers)
{
// If the path represented is a drive, then the child items are
// tables. get the names of all the tables in the drive.
if (PathIsDrive(path))
{
foreach (DatabaseTableInfo table in GetTables())
{
WriteItemObject(table.Name, path, true);
} // foreach (DatabaseTableInfo...
} // if (PathIsDrive...
else
{
// Get type, table name and row number from path specified
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Table)
{
// Get all the rows in the table and then write out the
// row numbers.
foreach (DatabaseRowInfo row in GetRows(tableName))
{
WriteItemObject(row.RowNumber, path, false);
} // foreach (DatabaseRowInfo...
}
else if (type == PathType.Row)
{
// In this case the user has directly specified a row, hence
// just give that particular row
DatabaseRowInfo row = GetRow(tableName, rowNumber);
WriteItemObject(row.RowNumber, path, false);
}
else
{
ThrowTerminatingInvalidPathException(path);
}
} // else
} // GetChildNames
Что нужно помнить о внедрении GetChildNames
К вашей реализации System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* могут применяться следующие условия:
При определении класса провайдера провайдер контейнеров Windows PowerShell может объявить возможности провайдера ExpandWildcards, Filter, Include или Exclude из перечисления System.Management.Automation.Provider.ProviderCapabilities . В таких случаях реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* должна гарантировать, что путь, переданный методу, соответствует требованиям указанных возможностей. Для этого метод должен получить доступ к соответствующим свойствам, например, к свойствам System.Management.Automation.Provider.CmdletProvider.Exclude* и свойствам System.Management.Automation.Provider.CmdletProvider.Include* .
Замечание
Исключение из этого правила возникает, когда
returnAllContainersпараметр cmdlet указан. В этом случае метод должен получать любое дочернее имя контейнера, даже если оно не совпадает с значениями свойств System.Management.Automation.Provider.Provider.CmdletProvider.Filter*, System.Management.Automation.Provider.CmdletProvider.Include* или System.Management.Automation.Provider.CmdletProvider.Exclude* .По умолчанию переопределения этого метода не должны получать имена объектов, которые обычно скрыты от пользователя, если не указано свойство System.Management.Automation.Provider.CmdletProvider.Force* . Если указанный путь указывает на контейнер, свойство System.Management.Automation.Provider.CmdletProvider.Force * не требуется.
Ваша реализация System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* отвечает за предотвращение бесконечной рекурсии при наличии круговых связей и тому подобного. Должно быть введено соответствующее исключение, отражающее такое условие.
Прикрепление динамических параметров к Get-ChildItem cmdlet (Name)
Иногда cmdlet Get-ChildItem (с параметром Name ) требует дополнительных параметров, которые задаются динамически во время выполнения. Для предоставления этих динамических параметров провайдер контейнеров Windows PowerShell должен реализовать метод System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNamesDynamicParameters* . Этот метод извлекает динамические параметры элемента по указанному пути и возвращает объект с свойствами и полями с атрибутами разбора, похожими на класс cmdlet или объект System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell использует возвращённый объект для добавления параметров в Get-ChildItem cmdlet.
Этот провайдер не реализует этот метод. Однако следующий код является стандартной реализацией этого метода.
Переименование предметов
Для переименования элемента провайдер контейнера Windows PowerShell должен переопределить метод System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* для поддержки вызовов из cmdlet Rename-Item . Этот метод меняет имя элемента на указанном пути на новое, предоставленное имя. Новое имя всегда должно быть относительно родительского элемента (контейнера).
Этот провайдер не отменяет метод System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* . Однако ниже приведена стандартная реализация.
Что нужно помнить о внедрении RenameItem
К вашей реализации System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* могут применяться следующие условия:
При определении класса провайдера провайдер контейнеров Windows PowerShell может объявить возможности провайдера ExpandWildcards, Filter, Include или Exclude из перечисления System.Management.Automation.Provider.ProviderCapabilities . В таких случаях реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* должна гарантировать, что путь, переданный методу, соответствует требованиям указанных возможностей. Для этого метод должен получить доступ к соответствующим свойствам, например, к свойствам System.Management.Automation.Provider.CmdletProvider.Exclude* и свойствам System.Management.Automation.Provider.CmdletProvider.Include* .
Метод System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* предназначен только для изменения имени элемента, а не для операций перемещения. Ваша реализация метода должна писать ошибку, если параметр
newNameсодержит разделители путей или может привести к изменению родительского положения элемента.По умолчанию переопределения этого метода не должны переименовывать объекты, если не указано свойство System.Management.Automation.Provider.CmdletProvider.Force* . Если указанный путь указывает на контейнер, свойство System.Management.Automation.Provider.CmdletProvider.Force * не требуется.
Ваша реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* должна вызывать System.Management.Automation.Provider.CmdletProvider.ShouldProcess и проверять его возвращаемое значение перед внесением изменений в хранилище данных. Этот метод используется для подтверждения выполнения операции при изменении состояния системы, например, при переименовании файлов. System.Management.Automation.Provider.CmdletProvider.ShouldProcess отправляет пользователю имя ресурса для изменения, при этом среда выполнения Windows PowerShell учитывает любые командные строки или переменные предпочтений при определении того, что должно отображаться.
После вызова System.Management.Automation.Provider.Provider.CmdletProvider.ShouldProcess возвращается
true, метод System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* должен вызывать метод System.Management.Automation.Provider.CmdletProvider.ShouldContinue . Этот метод отправляет пользователю подтверждение сообщения, чтобы получить дополнительную обратную связь с вопросом, следует ли продолжать операцию. Провайдер должен вызвать System.Management.Automation.Provider.CmdletProvider.ShouldContinue как дополнительную проверку на потенциально опасные модификации системы.
Прикрепление динамических параметров к командоустройству Rename-Item
Иногда cmdlet Rename-Item требует дополнительных параметров, которые динамически задаются во время выполнения. Для предоставления этих динамических параметров провайдер контейнеров Windows PowerShell должен реализовать метод System.Management.Automation.Provider.ContainerCmdletProvider.RenameItemDynamicParameters* . Этот метод извлекает параметры элемента по указанному пути и возвращает объект с свойствами и полями с атрибутами разбора, похожими на класс cmdlet или объект System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell использует возвращённый объект для добавления параметров в Rename-Item cmdlet.
Этот контейнерный провайдер не реализует этот метод. Однако следующий код является стандартной реализацией этого метода.
Создание новых предметов
Для создания новых элементов контейнерный провайдер должен реализовать метод System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* для поддержки вызовов из New-Item cmdlet. Этот метод создаёт элемент данных, расположенный на указанном пути. Параметр type cmdlet содержит тип, определённый провайдером для нового элемента. Например, провайдер FileSystem использует type параметр со значением «file» или «directory».
newItemValue Параметр cmdlet указывает значение, специфичное для провайдера, для нового элемента.
Вот реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* для этого провайдера.
protected override void NewItem( string path, string type, object newItemValue )
{
// Create the new item here after
// performing necessary validations
//
// WriteItemObject(newItemValue, path, false);
// Example
//
// if (ShouldProcess(path, "new item"))
// {
// // Create a new item and then call WriteObject
// WriteObject(newItemValue, path, false);
// }
} // NewItem
{
case 1:
{
string name = pathChunks[0];
if (TableNameIsValid(name))
{
tableName = name;
retVal = PathType.Table;
}
}
break;
case 2:
{
string name = pathChunks[0];
Что нужно помнить при внедрении NewItem
К вашей реализации System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* могут применяться следующие условия:
Метод System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* должен выполнять независимое от регистра сравнение строки, переданной в параметре
type. Это также должно позволять наименее неоднозначные совпадения. Например, для типов «file» и «directory» для разъяснения требуется только первая буква. Еслиtypeпараметр указывает на тип, который ваш провайдер не может создать, метод System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* должен написать ArgumentException с сообщением, указывающим типы, которые провайдер может создать.Для параметра
newItemValueрекомендуется реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* для принятия строк минимум. Он также должен принимать тип объекта, который получается методом System.Management.Automation.Provider.ItemCmdletProvider.GetItem* для того же пути. Метод System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* может использовать метод System.Management.Automation.LanguagePrimitives.ConvertTo* для преобразования типов в нужный тип.Ваша реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* должна вызывать System.Management.Automation.Provider.CmdletProvider.ShouldProcess и проверять его возвращаемое значение перед внесением изменений в хранилище данных. После вызова System.Management.Automation.Provider.Provider.CmdletProvider.ShouldProcess возвращает true, метод System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* должен вызвать метод System.Management.Automation.Provider.CmdletProvider.ShouldContinue как дополнительную проверку на потенциально опасные модификации системы.
Прикрепление динамических параметров к командоустройству New-Item
Иногда cmdlet New-Item требует дополнительных параметров, которые динамически задаются во время выполнения. Для предоставления этих динамических параметров контейнерный провайдер должен реализовать метод System.Management.Automation.Provider.ContainerCmdletProvider.NewItemDynamicParameters* . Этот метод извлекает параметры элемента по указанному пути и возвращает объект с свойствами и полями с атрибутами разбора, похожими на класс cmdlet или объект System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell использует возвращённый объект для добавления параметров в New-Item cmdlet.
Этот провайдер не реализует этот метод. Однако следующий код является стандартной реализацией этого метода.
Удаление предметов
Для удаления элементов провайдер Windows PowerShell должен переопределить метод System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* для поддержки вызовов из Remove-Item cmdlet. Этот метод удаляет элемент из хранилища данных на указанном пути. Если recurse параметр Remove-Item cmdlet установлен на true, метод удаляет все дочерние элементы независимо от их уровня. Если параметр установлен в false, метод удаляет только один элемент на указанном пути.
Этот провайдер не поддерживает удаление предметов. Однако следующий код является стандартной реализацией System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem*.
Что нужно помнить при внедрении RemoveItem
К вашей реализации System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* могут применяться следующие условия:
При определении класса провайдера провайдер контейнеров Windows PowerShell может объявить возможности провайдера ExpandWildcards, Filter, Include или Exclude из перечисления System.Management.Automation.Provider.ProviderCapabilities . В таких случаях реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* должна гарантировать, что путь, переданный методу, соответствует требованиям указанных возможностей. Для этого метод должен получить доступ к соответствующим свойствам, например, к свойствам System.Management.Automation.Provider.CmdletProvider.Exclude* и свойствам System.Management.Automation.Provider.CmdletProvider.Include* .
По умолчанию переопределения этого метода не должны удалять объекты, если свойство System.Management.Automation.Provider.Provider.CmdletProvider.Force* не установлено в true. Если указанный путь указывает на контейнер, свойство System.Management.Automation.Provider.CmdletProvider.Force * не требуется.
Ваша реализация System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* отвечает за предотвращение бесконечной рекурсии при наличии круговых связей и тому подобного. Должно быть введено соответствующее исключение, отражающее такое условие.
Ваша реализация метода System.Management.Automation.Provider.Provider.ContainerCmdletProvider.RemoveItem* должна вызывать System.Management.Automation.Provider.CmdletProvider.ShouldProcess и проверять его возвращаемое значение перед внесением изменений в хранилище данных. После вызова System.Management.Automation.Provider.CmdletProvider.ShouldProcess возвращается
true, метод System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* должен вызывать метод System.Management.Automation.Provider.CmdletProvider.ShouldContinue в качестве дополнительной проверки на потенциально опасные модификации системы.
Прикрепление динамических параметров к командоустройству Remove-Item
Иногда cmdlet Remove-Item требует дополнительных параметров, которые динамически задаются во время выполнения. Для предоставления этих динамических параметров контейнерный провайдер должен реализовать метод System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters* для обработки этих параметров. Этот метод извлекает динамические параметры элемента по указанному пути и возвращает объект с свойствами и полями с атрибутами разбора, похожими на класс cmdlet или объект System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell использует возвращённый объект для добавления параметров в Remove-Item cmdlet.
Этот контейнерный провайдер не реализует этот метод. Однако следующий код является стандартной реализацией System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters*.
Запросы для дочерних элементов
Чтобы проверить, существуют ли дочерние элементы на указанном пути, провайдер контейнеров Windows PowerShell должен переопределить метод System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* . Этот метод возвращается true , если у предмета есть почерние черти, и false в других случаях. Для нулевого или пустого пути метод считает любые элементы в хранилище данных дочерними и возвращает true.
Вот переопределение для метода System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* . Если с помощью вспомогательного метода ChunkPath создаётся более двух частей пути, метод возвращает false, поскольку определены только контейнер базы данных и контейнер таблицы. Для получения дополнительной информации об этом вспомогательном методе см. метод ChunkPath обсуждается в статье «Создание провайдера элементов Windows PowerShell».
protected override bool HasChildItems( string path )
{
return false;
} // HasChildItems
ErrorCategory.InvalidOperation, tableName));
}
return results;
Что нужно помнить о внедрении HasChildItems
К вашей реализации System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* могут применяться следующие условия:
- Если провайдер контейнера открывает корень с интересными точками монтирования, реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* должна возвращаться
trueпри передаче нулевой или пустой строки для пути.
Копирование предметов
Для копирования элементов поставщик контейнера должен реализовать метод System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem для поддержки вызовов из Copy-Item cmdlet. Этот метод копирует элемент данных из места, указанного path параметром cmdlet, в указанное параметром copyPath . Если recurse параметр указан, метод копирует все подконтейнеры. Если параметр не указан, метод копирует только один уровень элементов.
Этот провайдер не реализует этот метод. Однако следующий код является стандартной реализацией System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem.
Что нужно помнить о внедрении CopyItem
Следующие условия могут применяться к вашей реализации System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem:
При определении класса провайдера провайдер контейнеров Windows PowerShell может объявить возможности провайдера ExpandWildcards, Filter, Include или Exclude из перечисления System.Management.Automation.Provider.ProviderCapabilities . В таких случаях реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* должна гарантировать, что путь, переданный методу, соответствует требованиям указанных возможностей. Для этого метод должен получить доступ к соответствующим свойствам, например, к свойствам System.Management.Automation.Provider.CmdletProvider.Exclude* и свойствам System.Management.Automation.Provider.CmdletProvider.Include* .
По умолчанию переопределители этого метода не должны копировать объекты на существующие, если только свойство System.Management.Automation.Provider.Provider.CmdletProvider.Force* не установлено на
true. Например, провайдер FileSystem не сможет скопировать C:\temp\abc.txt на существующий C:\abc.txt файл, если свойство System.Management.Automation.Provider.CmdletProvider.Force* не установлено наtrue. Если указанный вcopyPathпараметре путь существует и указывает на контейнер, свойство System.Management.Automation.Provider.CmdletProvider.Force * не требуется. В этом случае System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem должен скопировать элемент, указанныйpathпараметром, в контейнер, указанныйcopyPathпараметром как дочерний параметр.Ваша реализация System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem отвечает за предотвращение бесконечной рекурсии при наличии круговых связей и тому подобного. Должно быть введено соответствующее исключение, отражающее такое условие.
Ваша реализация метода System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem должна вызывать System.Management.Automation.Provider.CmdletProvider.ShouldProcess и проверять его возвращаемое значение перед внесением изменений в хранилище данных. После вызова System.Management.Automation.Provider.CmdletProvider.ShouldProcess возвращает true, метод System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem должен вызывать метод System.Management.Automation.Provider.CmdletProvider.ShouldContinue в качестве дополнительной проверки на потенциально опасные модификации системы. Для получения дополнительной информации о вызове этих методов см. раздел «Переименование предметов».
Прикрепление динамических параметров к командоустройству Copy-Item
Иногда cmdlet Copy-Item требует дополнительных параметров, которые динамически задаются во время выполнения. Для предоставления этих динамических параметров поставщик контейнеров Windows PowerShell должен реализовать метод System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters* для обработки этих параметров. Этот метод извлекает параметры элемента по указанному пути и возвращает объект с свойствами и полями с атрибутами разбора, похожими на класс cmdlet или объект System.Management.Automation.RuntimeDefinedParameterDictionary . Runtime Windows PowerShell использует возвращённый объект для добавления параметров в Copy-Item cmdlet.
Этот провайдер не реализует этот метод. Однако следующий код является стандартной реализацией System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*.
Пример кода
Полный пример кода см. AccessDbProviderSample04 Code Sample.
Создание провайдера Windows PowerShell
Посмотрите, как зарегистрировать cmdlet, провайдеров и хост-приложения.
Тестирование провайдера Windows PowerShell
Когда ваш провайдер Windows PowerShell зарегистрирован в Windows PowerShell, вы можете проверить это, запустив поддерживаемые cmdlets в командной строке. Обратите внимание, что следующий пример вывода использует фиктивную базу данных Access.
Запустите
Get-ChildItemcmdlet, чтобы получить список дочерних элементов из таблицы Customers в базе данных Access.Get-ChildItem mydb:customersНиже приводится результат.
PSPath : AccessDB::customers PSDrive : mydb PSProvider : System.Management.Automation.ProviderInfo PSIsContainer : True Data : System.Data.DataRow Name : Customers RowCount : 91 Columns :Запустите
Get-ChildItemcmdlet снова, чтобы получить данные таблицы.(Get-ChildItem mydb:customers).DataНиже приводится результат.
TABLE_CAT : C:\PS\northwind TABLE_SCHEM : TABLE_NAME : Customers TABLE_TYPE : TABLE REMARKS :Теперь используйте
Get-Itemcmdlet, чтобы получить элементы в строке 0 в таблице данных.Get-Item mydb:\customers\0Ниже приводится результат.
PSPath : AccessDB::customers\0 PSDrive : mydb PSProvider : System.Management.Automation.ProviderInfo PSIsContainer : False Data : System.Data.DataRow RowNumber : 0Повторное использование
Get-Itemдля получения данных для элементов в строке 0.(Get-Item mydb:\customers\0).DataНиже приводится результат.
CustomerID : 1234 CompanyName : Fabrikam ContactName : Eric Gruber ContactTitle : President Address : 4567 Main Street City : Buffalo Region : NY PostalCode : 98052 Country : USA Phone : (425) 555-0100 Fax : (425) 555-0101Теперь используйте
New-Itemcmdlet, чтобы добавить строку в существующую таблицу.PathПараметр задаёт полный путь к строке и должен указывать номер строки, который превышает существующее количество строк в таблице. ПараметрTypeуказываетRowна то, какой тип элемента нужно добавить. Наконец,Valueпараметр задаёт список значений столбцов, разделённый запятой, для строки.New-Item -Path mydb:\Customers\3 -ItemType "Row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"Проверьте корректность операции нового элемента следующим образом.
PS mydb:\> cd Customers PS mydb:\Customers> (Get-Item 3).DataНиже приводится результат.
ID : 3 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
См. также
Создание провайдеров Windows PowerShell
Проектирование вашего провайдера Windows PowerShell
Реализация поставщика PowerShell для Windows
Реализация навигационного провайдера Windows PowerShell