Compartir a través de


Creación de un proveedor de navegación de Windows PowerShell

En este tema se describe cómo crear un proveedor de navegación de Windows PowerShell que pueda navegar por el almacén de datos. Este tipo de proveedor admite comandos recursivos, contenedores anidados y rutas de acceso relativas.

Nota:

Puede descargar el archivo de código fuente de C# (AccessDBSampleProvider05.cs) para este proveedor mediante el Kit de desarrollo de software de Microsoft Windows para Windows Vista y componentes en tiempo de ejecución de .NET Framework 3.0. Para obtener instrucciones de descarga, consulte Cómo instalar Windows PowerShell y Descargar el SDK de Windows PowerShell. Los archivos de código fuente descargados están disponibles en el directorio>ejemplos de PowerShell de<. Para obtener más información sobre otras implementaciones del proveedor de Windows PowerShell, consulte Diseño del proveedor de Windows PowerShell.

El proveedor descrito aquí permite al usuario controlar una base de datos de Access como una unidad para que el usuario pueda navegar a las tablas de datos de la base de datos. Al crear su propio proveedor de navegación, puede implementar métodos que pueden hacer que las rutas de acceso aptas para unidades sean necesarias para la navegación, normalizar rutas de acceso relativas, mover elementos del almacén de datos, así como métodos que obtienen nombres secundarios, obtener la ruta de acceso primaria de un elemento y probar para identificar si un elemento es un contenedor.

Precaución

Tenga en cuenta que este diseño supone una base de datos que tiene un campo con el identificador de nombre y que el tipo del campo es LongInteger.

Definición del proveedor de Windows PowerShell

Un proveedor de navegación de Windows PowerShell debe crear una clase .NET que derive de la clase base System.Management.Automation.Provider.NavigationCmdletProvider. Esta es la definición de clase para el proveedor de navegación descrito en esta sección.

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

Tenga en cuenta que en este proveedor, el atributo System.Management.Automation.Provider.CmdletProviderAttribute incluye dos parámetros. El primer parámetro especifica un nombre descriptivo para el proveedor que usa Windows PowerShell. El segundo parámetro especifica las funcionalidades específicas de Windows PowerShell que el proveedor expone al entorno de ejecución de Windows PowerShell durante el procesamiento de comandos. Para este proveedor, no hay ninguna funcionalidad específica de Windows PowerShell que se agregue.

Definición de la funcionalidad base

Tal como se describe en Diseñar el proveedor de PS, la clase base System.Management.Automation.Provider.NavigationCmdletProvider deriva de varias otras clases que proporcionaban diferentes funcionalidades de proveedor. Por lo tanto, un proveedor de navegación de Windows PowerShell debe definir toda la funcionalidad proporcionada por esas clases.

Para implementar la funcionalidad para agregar información de inicialización específica de la sesión y para liberar recursos que usa el proveedor, consulte Creación de un proveedor de PS básico. Sin embargo, la mayoría de los proveedores (incluido el proveedor descrito aquí) pueden usar la implementación predeterminada de esta funcionalidad proporcionada por Windows PowerShell.

Para obtener acceso al almacén de datos a través de una unidad de Windows PowerShell, debe implementar los métodos de la clase base System.Management.Automation.Provider.DriveCmdletProvider. Para obtener más información sobre cómo implementar estos métodos, vea Creación de un proveedor de unidades de Windows PowerShell.

Para manipular los elementos de un almacén de datos, como obtener, establecer y borrar elementos, el proveedor debe implementar los métodos proporcionados por la clase base System.Management.Automation.Provider.ItemCmdletProvider. Para obtener más información sobre cómo implementar estos métodos, vea Creación de un proveedor de elementos de Windows PowerShell.

Para llegar a los elementos secundarios, o a sus nombres, del almacén de datos, así como a los métodos que crean, copian, cambian el nombre y quitan elementos, debe implementar los métodos proporcionados por la clase base System.Management.Automation.Provider.ContainerCmdletProvider. Para obtener más información sobre cómo implementar estos métodos, vea Creación de un proveedor de contenedores de Windows PowerShell.

Creación de una ruta de acceso de Windows PowerShell

El proveedor de navegación de Windows PowerShell usa una ruta de acceso interna de Windows PowerShell del proveedor para navegar por los elementos del almacén de datos. Para crear una ruta de acceso interna del proveedor, el proveedor debe implementar el método System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* para admitir llamadas desde el cmdlet Combine-Path. Este método combina una ruta de acceso primaria y secundaria en una ruta de acceso interna del proveedor mediante un separador de ruta de acceso específico del proveedor entre las rutas de acceso primaria y secundaria.

La implementación predeterminada toma rutas de acceso con "/" o "\" como separador de ruta de acceso, normaliza el separador de ruta de acceso a "\", combina los elementos de ruta de acceso primarios y secundarios con el separador entre ellos y, a continuación, devuelve una cadena que contiene las rutas de acceso combinadas.

Este proveedor de navegación no implementa este método. Sin embargo, el código siguiente es la implementación predeterminada del método System.Management.Automation.Provider.NavigationCmdletProvider.MakePath*.

Cosas que recordar sobre la implementación de MakePath

Las condiciones siguientes pueden aplicarse a la implementación de System.Management.Automation.Provider.NavigationCmdletProvider.MakePath*:

  • La implementación del método System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* no debe validar la ruta de acceso como una ruta de acceso completa legal en el espacio de nombres del proveedor. Tenga en cuenta que cada parámetro solo puede representar una parte de una ruta de acceso y es posible que las partes combinadas no generen una ruta de acceso completa. Por ejemplo, el método System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* para el proveedor FileSystem podría recibir "windows\system32" en el parámetro parent y "abc.dll" en el parámetro child. El método combina estos valores con el separador "\" y devuelve "windows\system32\abc.dll", que no es una ruta de acceso completa del sistema de archivos.

    Importante

    Los elementos de ruta de acceso proporcionados en la llamada a System.Management.Automation.Provider.NavigationCmdletProvider.MakePath* pueden contener caracteres no permitidos en el espacio de nombres del proveedor. Estos caracteres se usan con mayor probabilidad para la expansión de caracteres comodín y la implementación de este método no debe quitarlos.

Recuperación de la ruta de acceso primaria

Los proveedores de navegación de Windows PowerShell implementan el método System.Management.Automation.Provider.NavigationCmdletProvider.GetParentPath* para recuperar la parte primaria de la ruta de acceso completa o parcial específica del proveedor indicada. El método quita la parte secundaria de la ruta de acceso y devuelve la parte de ruta de acceso primaria. El parámetro root especifica la ruta de acceso completa a la raíz de una unidad. Este parámetro puede ser null o estar vacío si una unidad montada no está en uso para la operación de recuperación. Si se especifica una raíz, el método debe devolver una ruta de acceso a un contenedor del mismo árbol que la raíz.

El proveedor de navegación de ejemplo no invalida este método, pero usa la implementación predeterminada. Acepta rutas de acceso que usan "/" y "\" como separadores de ruta de acceso. Normaliza primero la ruta de acceso para tener solo separadores "\", y luego divide la ruta de acceso primaria en la última "\" y devuelve la ruta de acceso primaria.

Para recordar la implementación de GetParentPath

La implementación del método System.Management.Automation.Provider.NavigationCmdletProvider.GetParentPath* debe dividir la ruta de acceso léxicamente en el separador de ruta de acceso para el espacio de nombres del proveedor. Por ejemplo, el proveedor FileSystem usa este método para buscar el último "\" y devuelve todo a la izquierda del separador.

Recuperar el nombre de la ruta de acceso secundaria

El proveedor de navegación implementa el método System.Management.Automation.Provider.NavigationCmdletProvider.GetChildName* para recuperar el nombre (elemento hoja) del elemento secundario del elemento ubicado en la ruta de acceso completa o parcial específica del proveedor indicada.

El proveedor de navegación de ejemplo no invalida este método. A continuación se muestra la implementación predeterminada. Acepta rutas de acceso que usan "/" y "\" como separadores de ruta de acceso. Normaliza primero la ruta de acceso para tener solo separadores "\", y luego divide la ruta de acceso primaria en la última "\" y devuelve el nombre de la parte de ruta de acceso secundaria.

Cosas que recordar sobre la implementación de GetChildName

La implementación del método System.Management.Automation.Provider.NavigationCmdletProvider.GetChildName* debe dividir la ruta de acceso léxicamente en el separador de ruta de acceso. Si la ruta de acceso proporcionada no contiene separadores de ruta de acceso, el método debe devolver la ruta de acceso sin modificar.

Importante

La ruta de acceso proporcionada en la llamada a este método puede contener caracteres que no son válidos en el espacio de nombres del proveedor. Es más probable que estos caracteres se usen para la expansión de caracteres comodín o la coincidencia de expresiones regulares, y la implementación de este método no debe quitarlos.

Determinar si un elemento es un contenedor

El proveedor de navegación puede implementar el método System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* para determinar si la ruta de acceso especificada indica un contenedor. Devuelve true si la ruta de acceso representa un contenedor y false de lo contrario. El usuario necesita que este método pueda usar el cmdlet Test-Path para la ruta de acceso proporcionada.

En el código siguiente se muestra la implementación de System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* en nuestro proveedor de navegación de ejemplo. El método comprueba que la ruta de acceso especificada es correcta y si la tabla existe y devuelve true si la ruta de acceso indica un contenedor.

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

Cosas que recordar sobre la implementación de IsItemContainer

La clase .NET del proveedor de navegación podría declarar funcionalidades de proveedor de ExpandWildcards, Filter, Include o Exclude de la enumeración System.Management.Automation.Provider.ProviderCapabilities. En este caso, la implementación de System.Management.Automation.Provider.NavigationCmdletProvider.IsItemContainer* debe asegurarse de que la ruta de acceso pasada cumple los requisitos. Para ello, el método debe tener acceso a la propiedad adecuada, por ejemplo, la propiedad System.Management.Automation.Provider.CmdletProvider.Exclude*.

Mover un elemento

En compatibilidad con el cmdlet Move-Item, el proveedor de navegación implementa el método System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem*. Este método mueve el elemento especificado por el parámetro path al contenedor en la ruta de acceso proporcionada en el parámetro destination.

El proveedor de navegación de ejemplo no invalida el método System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem*. A continuación se muestra la implementación predeterminada.

Cosas que recordar sobre la implementación de MoveItem

La clase .NET del proveedor de navegación podría declarar funcionalidades de proveedor de ExpandWildcards, Filter, Include o Exclude de la enumeración System.Management.Automation.Provider.ProviderCapabilities. En este caso, la implementación de System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* debe asegurarse de que la ruta de acceso superada cumple los requisitos. Para ello, el método debe tener acceso a la propiedad adecuada, por ejemplo, la propiedad CmdletProvider.Exclude.

De forma predeterminada, las invalidaciones de este método no deben mover objetos sobre objetos existentes a menos que la propiedad System.Management.Automation.Provider.CmdletProvider.Force* esté establecida en true. Por ejemplo, el proveedor FileSystem no copiará C:\temp\abc.txt en un archivo de C:\bar.txt existente a menos que la propiedad System.Management.Automation.Provider.CmdletProvider.Force* esté establecida en true. Si la ruta de acceso especificada en el parámetro destination existe y es un contenedor, no se requiere la propiedad System.Management.Automation.Provider.CmdletProvider.Force*. En este caso, System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* debe mover el elemento indicado por el parámetro path al contenedor indicado por el parámetro destination como elemento secundario.

La implementación del método System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* debe llamar a System.Management.Automation.Provider.CmdletProvider.ShouldProcess y comprobar su valor devuelto antes de realizar cambios en el almacén de datos. Este método se usa para confirmar la ejecución de una operación cuando se realiza un cambio en el estado del sistema, por ejemplo, eliminando archivos. System.Management.Automation.Provider.CmdletProvider.ShouldProcess envía el nombre del recurso que se va a cambiar al usuario, con el tiempo de ejecución de Windows PowerShell teniendo en cuenta cualquier configuración de línea de comandos o variables de preferencia para determinar lo que se debe mostrar al usuario.

Después de la llamada a System.Management.Automation.Provider.CmdletProvider.ShouldProcess devuelve true, el método System.Management.Automation.Provider.NavigationCmdletProvider.MoveItem* debe llamar al método System.Management.Automation.Provider.CmdletProvider.ShouldContinue. Este método envía un mensaje al usuario para permitir que los comentarios digan si se debe continuar la operación. El proveedor debe llamar a System.Management.Automation.Provider.CmdletProvider.ShouldContinue como una comprobación adicional de las modificaciones del sistema potencialmente peligrosas.

Asociación de parámetros dinámicos al cmdlet de Move-Item

A veces, el cmdlet Move-Item requiere parámetros adicionales que se proporcionan dinámicamente en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor de navegación debe implementar el método System.Management.Automation.Provider.NavigationCmdletProvider.MoveItemDynamicParameters* para obtener los valores de parámetro necesarios del elemento en la ruta de acceso indicada y devolver un objeto que tenga propiedades y campos con atributos de análisis similares a una clase de cmdlet o a un objeto System.Management.Automation.RuntimeDefinedParameterDiction ary.

Este proveedor de navegación no implementa este método. Sin embargo, el código siguiente es la implementación predeterminada de System.Management.Automation.Provider.NavigationCmdletProvider.MoveItemDynamicParameters*.

Normalización de una ruta de acceso relativa

El proveedor de navegación implementa el método System.Management.Automation.Provider.NavigationCmdletProvider.NormalizeRelativePath* para normalizar la ruta de acceso completa indicada en el parámetro path como relativo a la ruta de acceso especificada por el parámetro basePath. El método devuelve una representación de cadena de la ruta de acceso normalizada. Escribe un error si el parámetro path especifica una ruta de acceso inexistente.

El proveedor de navegación de ejemplo no invalida este método. A continuación se muestra la implementación predeterminada.

Cosas que recordar sobre la implementación de NormalizeRelativePath

La implementación de System.Management.Automation.Provider.NavigationCmdletProvider.NormalizeRelativePath* debe analizar el parámetro path, pero no tiene que usar el análisis puramente sintáctico. Se recomienda diseñar este método para usar la ruta de acceso para buscar la información de ruta de acceso en el almacén de datos y crear una ruta de acceso que coincida con la sintaxis de la ruta de acceso estandarizada y mayúsculas.

Ejemplo de código

Para obtener código de ejemplo completo, consulte ejemplo de código AccessDbProviderSample05.

Definición de tipos de objeto y formato

Es posible que un proveedor agregue miembros a objetos existentes o defina nuevos objetos. Para obtener más información, veaextensión de tipos de objeto y formato.

Compilación del proveedor de Windows PowerShell

Para obtener más información, consulte Registro de cmdlets, proveedores y aplicaciones host.

Prueba del proveedor de Windows PowerShell

Cuando el proveedor de Windows PowerShell se ha registrado con Windows PowerShell, puede probarlo ejecutando los cmdlets admitidos en la línea de comandos, incluidos los cmdlets disponibles por derivación. En este ejemplo se probará el proveedor de navegación de ejemplo.

  1. Ejecute el nuevo shell y use el cmdlet Set-Location para establecer la ruta de acceso para indicar la base de datos de Access.

    Set-Location mydb:
    
  2. Ahora ejecute el cmdlet Get-ChildItem para recuperar una lista de los elementos de base de datos, que son las tablas de base de datos disponibles. Para cada tabla, este cmdlet también recupera el número de filas de tabla.

    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. Use de nuevo el cmdlet Set-Location para establecer la ubicación de la tabla de datos Employees.

    Set-Location Employees
    
  4. Ahora vamos a usar el cmdlet Get-Location para recuperar la ruta de acceso a la tabla Employees.

    Get-Location
    
    Path
    ----
    mydb:\Employees
    
  5. Ahora use el cmdlet Get-ChildItem canalización al cmdlet Format-Table. Este conjunto de cmdlets recupera los elementos de la tabla de datos Employees, que son las filas de la tabla. Tienen el formato especificado por el cmdlet Format-Table.

    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. Ahora puede ejecutar el cmdlet Get-Item para recuperar los elementos de la fila 0 de la tabla de datos 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. Use de nuevo el cmdlet Get-Item para recuperar los datos de los empleados de los elementos de la fila 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
    

Véase también

creación de proveedores de Windows PowerShell

diseñar el proveedor de Windows PowerShell

extensión de tipos de objeto y formato

Implementación de un proveedor de Windows PowerShell de contenedor

Registro de cmdlets, proveedores y aplicaciones host

guía del programador de Windows PowerShell

del SDK de Windows PowerShell