Поделиться через


Создание провайдера навигации для Windows PowerShell

В этой теме описывается, как создать навигационного провайдера Windows PowerShell, который сможет ориентироваться в хранилище данных. Этот тип провайдера поддерживает рекурсивные команды, вложенные контейнеры и относительные пути.

Замечание

Вы можете скачать исходный файл на C# (AccessDBSampleProvider05.cs) для этого провайдера с помощью Microsoft Windows Software Development Kit for Windows Vista и компонентов выполнения .NET Framework 3.0. Инструкции по скачиванию смотрите в разделе «Как установить Windows PowerShell» и «Скачать Windows PowerShell SDK». Загруженные исходные файлы доступны в каталоге <PowerShell Samples> . Для получения дополнительной информации о других реализациях провайдеров Windows PowerShell см. раздел «Проектирование вашего провайдера Windows PowerShell».

Описанный здесь провайдер позволяет пользователю управлять базой данных Access как диск, чтобы пользователь мог переходить к таблицам данных в базе данных. При создании собственного навигационного провайдера вы можете реализовать методы, которые делают требуемые для навигации квалифицированные для диска, нормализуют относительные пути, перемещают элементы хранилища данных, а также методы, получающие дочерние имена, родительский путь предмета и тестирующие для определения контейнера.

Caution

Имейте в виду, что эта конструкция предполагает наличие базы данных с полем с идентификатором имени, и тип поля — LongInwhole число.

Определите провайдера Windows PowerShell

Навигационный провайдер Windows PowerShell должен создать класс .NET, который производится из базового класса System.Management.Automation.Provider.NavigationCmdletProvider . Вот определение класса для навигационного провайдера, описанного в этом разделе.

[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : NavigationCmdletProvider

Обратите внимание, что в этом провайдере атрибут System.Management.Automation.Provider.CmdletProviderAttribute включает два параметра. Первый параметр задаёт удобное для пользователя имя провайдера, используемое Windows PowerShell. Второй параметр определяет специфические для Windows PowerShell возможности, которые провайдер открывает в процессе выполнения Windows PowerShell во время обработки команд. Для этого провайдера нет добавленных специфических возможностей Windows PowerShell.

Определение базовой функциональности

Как описано в статье Design Your PS Provider, базовый класс 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* не должна подтверждать путь как легальный полностью квалифицированный путь в пространстве имён провайдера. Имейте в виду, что каждый параметр может представлять только часть пути, и объединённые части могут не создавать полностью квалифицированный путь. Например, метод System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* для провайдера файловой системы может получать «windows\system32» в parent параметре и «abc.dll» в параметре child . Метод соединяет эти значения с разделителем «\» и возвращает «Windows\system32\abc.dll», который не является полностью квалифицированным путём файловой системы.

    Это важно

    Части пути, предоставленные в вызове System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* , могут содержать символы, не разрешённые в пространстве имён провайдера. Эти персонажи, скорее всего, используются для расширения джокеров, и реализация этого метода не должна их убирать.

Получение родительского пути

Навигационные провайдеры Windows PowerShell реализуют метод System.Management.Automation.Provider.NavigationCmdletProvider.GetParentPath* для получения родительской части указанного полного или частичного пути, специфичного для провайдера. Метод удаляет дочернюю часть пути и возвращает родительскую часть. Параметр root задаёт полностью квалифицированный путь к корню диска. Этот параметр может быть обнулён или пуст, если установленный диск не используется для операции извлечения. Если указан корень, метод должен вернуть путь в контейнер в том же дереве, что и корень.

Примерный навигационный провайдер не отменяет этот метод, а использует стандартную реализацию. Он принимает пути, которые используют как разделители путей, так и «/» и «\». Сначала он нормализует путь с разделителями только «\», затем разделяет родительский путь на последнем «\» и возвращает родительский путь.

Помните, как внедрять GetParentPath

Ваша реализация метода System.Management.Automation.Provider.NavigationCmdletProvider.GetParentPath* должна лексически разбить путь на разделителе путей для пространства имён провайдера. Например, провайдер FileSystem использует этот метод для поиска последнего «\» и возвращает всё слева от сепаратора.

Получить имя дочернего пути

Ваш навигационный провайдер реализует метод System.Management.Automation.Provider.NavigationCmdletProvider.GetChildName* для извлечения имени (элемента leaf) дочернего элемента, расположенного на указанном полном или частичном пути, специфичном для провайдера.

Примерный навигационный провайдер не отменяет этот метод. Ниже приведена реализация по умолчанию. Он принимает пути, которые используют как разделители путей, так и «/» и «\». Сначала он нормализует путь с разделителями только «\», затем разделяет родительский путь на последнем «\» и возвращает имя дочерней части.

Что нужно помнить о внедрении GetChildName

Ваша реализация метода System.Management.Automation.Provider.NavigationCmdletProvider.GetChildName* должна лексически разделять путь на разделителе путей. Если предоставленный путь не содержит разделителей путей, метод должен возвращать путь без изменений.

Это важно

Путь, предоставленный в вызове этого метода, может содержать символы, нелегальные в пространстве имён провайдера. Эти символы, скорее всего, используются для расширения по дикой карте или сопоставлению регулярных выражений, и реализация этого метода не должна их убирать.

Определение, является ли предмет контейнером

Навигационный провайдер может реализовать метод System.Management.Automation.Provider.Navigation.CmdletProvider.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 класс может объявить возможности провайдера ExpandWildcards, Filter, Include или Exclude из перечисления System.Management.Automation.Provider.ProviderCapabilities . В этом случае реализация 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 класс может объявить возможности провайдера ExpandWildcards, Filter, Include или Exclude из перечисления System.Management.Automation.Provider.ProviderCapabilities . В этом случае реализация System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* должна гарантировать, что пройденный путь соответствует требованиям. Для этого метод должен получить доступ к соответствующему свойству, например, к свойству CmdletProvider.Excluded .

По умолчанию переопределения этого метода не должны перемещать объекты по существующим объектам, если свойство System.Management.Automation.Provider.Provider.CmdletProvider.Force* не установлено на true. Например, провайдер FileSystem не сможет скопировать C:\temp\abc.txt на существующий C:\bar.txt файл, если свойство System.Management.Automation.Provider.CmdletProvider.Force* не установлено на true. Если путь, destination указанный в параметре, существует и является контейнером, свойство System.Management.Automation.Provider.CmdletProvider.Force * не требуется. В этом случае System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* должен переместить элемент, указанный path параметром, в контейнер, обозначенный destination параметром как дочерний параметр.

Ваша реализация метода System.Management.Automation.Provider.Provider.NavigationCmdletProvider.MoveItem* должна вызывать 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.NavigationCmdletProvider.MoveItem* должен вызывать метод System.Management.Automation.Provider.CmdletProvider.ShouldContinue . Этот метод отправляет пользователю сообщение, чтобы получить обратную связь и сообщать, следует ли продолжать операцию. Ваш провайдер должен позвонить в System.Management.Automation.Provider.CmdletProvider.ShouldContinue для дополнительной проверки на потенциально опасные модификации системы.

Прикрепление динамических параметров к командоустройству Move-Item

Иногда cmdlet Move-Item требует дополнительных параметров, которые предоставляются динамически во время выполнения. Для предоставления этих динамических параметров навигационный провайдер должен реализовать метод 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 Code Sample05.

Определение типов объектов и форматирования

Провайдер может добавлять члены к существующим объектам или определять новые. Для получения дополнительной информации см.раздел «Расширение типов объектов и форматирования».

Создание провайдера Windows PowerShell

Для получения дополнительной информации смотрите раздел «Как зарегистрировать команды, поставщиков и хост-приложений».

Тестирование провайдера Windows PowerShell

Когда ваш провайдер Windows PowerShell зарегистрирован в Windows PowerShell, вы можете проверить это, запустив поддерживаемые командные команды в командной строке, включая cmdlet, доступные по производной системе. В этом примере будет протестирован поставщик навигации примера.

  1. Запустите новую оболочку и используйте Set-Location cmdlet, чтобы задать путь для обозначения базы данных Access.

    Set-Location mydb:
    
  2. Теперь запустите 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
    
  3. Используйте Set-Location cmdlet ещё раз, чтобы задать расположение таблицы данных Сотрудников.

    Set-Location Employees
    
  4. Теперь давайте используем Get-Location cmdlet, чтобы получить путь к таблице Employees.

    Get-Location
    
    Path
    ----
    mydb:\Employees
    
  5. Теперь используйте cmdlet, Get-ChildItem подключённый к cmdlet Format-Table . Этот набор командоров извлекает элементы для таблицы данных Сотрудников, то есть строки таблицы. Они форматируются в соответствии с указанием 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
    
  6. Теперь вы можете запустить Get-Item cmdlet, чтобы получить элементы для строки 0 таблицы данных Employees.

    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
    
  7. Используйте 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
    

См. также

Создание провайдеров Windows PowerShell

Спроектируйте своего провайдера Windows PowerShell

Расширение типов объектов и форматирование

Реализовать контейнерный провайдер Windows PowerShell

Как зарегистрировать cmdlet, провайдеров и хост-приложений

Руководство программиста Windows PowerShell

Windows PowerShell SDK