Guida introduttiva del provider di Windows PowerShell

In questo argomento viene illustrato come creare un provider Windows PowerShell con funzionalità di base per la creazione di una nuova unità. Per informazioni generali sui provider, vedere Panoramica Windows PowerShell provider. Per esempi di provider con funzionalità più complete, vedere Esempi di provider.

Scrittura di un provider di base

La funzionalità più semplice di un provider Windows PowerShell è la creazione e la rimozione di unità. In questo esempio vengono implementati i metodi System.Management.Automation.Provider.Drivecmdletprovider.Newdrive* e System.Management.Automation.Provider.Drivecmdletprovider.Removedrive* della classe System.Management.Automation.Provider.Drivecmdletprovider. Verrà inoltre illustrato come dichiarare una classe provider.

Quando si scrive un provider, è possibile specificare unità predefinite create automaticamente quando il provider è disponibile. Si definisce anche un metodo per creare nuove unità che usano tale provider.

Gli esempi forniti in questo argomento si basano sull'esempio AccessDBProviderSample02, che fa parte di un esempio più ampio che rappresenta un database di Access come unità Windows PowerShell dati.

Configurazione del progetto

In Visual Studio creare un progetto Libreria di classi denominato AccessDBProviderSample. Completare i passaggi seguenti per configurare il progetto in modo che Windows PowerShell verrà avviato e il provider verrà caricato nella sessione, quando si compila e si avvia il progetto.

Configurare il progetto provider
  1. Aggiungere l'assembly System.Management.Automation come riferimento al progetto.

  2. Fare Project > proprietà AccessDBProviderSample > Debug. In Avvia progetto fare clic su Avvia programma esterno e passare al file eseguibile di Windows PowerShell (in genere c:\Windows\System32\WindowsPowerShell\v1.0 \ .powershell.exe).

  3. In Opzioni di avvio immettere quanto segue nella casella Argomenti della riga di comando: -noexit -command "[reflection.assembly]::loadFrom(AccessDBProviderSample.dll' ) | import-module"

Dichiarazione della classe provider

Il provider deriva dalla classe System.Management.Automation.Provider.Drivecmdletprovider. La maggior parte dei provider che forniscono funzionalità reali (accesso e modifica degli elementi, spostamento nell'archivio dati e recupero e impostazione del contenuto degli elementi) derivano dalla classe System.Management.Automation.Provider.Navigationcmdletprovider.

Oltre a specificare che la classe deriva da System.Management.Automation.Provider.Drivecmdletprovider, è necessario decorarla con System.Management.Automation.Provider.Cmdletproviderattribute, come illustrato nell'esempio.

namespace Microsoft.Samples.PowerShell.Providers
{
  using System;
  using System.Data;
  using System.Data.Odbc;
  using System.IO;
  using System.Management.Automation;
  using System.Management.Automation.Provider;

  #region AccessDBProvider

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

}
}

Implementazione di NewDrive

Il metodo System.Management.Automation.Provider.Drivecmdletprovider.Newdrive* viene chiamato dal motore Windows PowerShell quando un utente chiama il cmdlet Microsoft.PowerShell.Commands.NewPSDriveCommand specificando il nome del provider. Il parametro PSDriveInfo viene passato dal motore Windows PowerShell e il metodo restituisce la nuova unità al Windows PowerShell motore. Questo metodo deve essere dichiarato all'interno della classe creata in precedenza.

Il metodo verifica prima di tutto che esistano sia l'oggetto unità che la radice dell'unità passati, che restituisce in caso null contrario. Usa quindi un costruttore della classe interna AccessDBPSDriveInfo per creare una nuova unità e una connessione al database di Access rappresentato dall'unità.

protected override PSDriveInfo NewDrive(PSDriveInfo drive)
    {
      // Check if the drive object is null.
      if (drive == null)
      {
        WriteError(new ErrorRecord(
                   new ArgumentNullException("drive"),
                   "NullDrive",
                   ErrorCategory.InvalidArgument,
                   null));

        return null;
      }

      // Check if the drive root is not null or empty
      // and if it is an existing file.
      if (String.IsNullOrEmpty(drive.Root) || (File.Exists(drive.Root) == false))
      {
        WriteError(new ErrorRecord(
                   new ArgumentException("drive.Root"),
                   "NoRoot",
                   ErrorCategory.InvalidArgument,
                   drive));

        return null;
      }

      // Create a new drive and create an ODBC connection to the new drive.
      AccessDBPSDriveInfo accessDBPSDriveInfo = new AccessDBPSDriveInfo(drive);
      OdbcConnectionStringBuilder builder = new OdbcConnectionStringBuilder();

      builder.Driver = "Microsoft Access Driver (*.mdb)";
      builder.Add("DBQ", drive.Root);

      OdbcConnection conn = new OdbcConnection(builder.ConnectionString);
      conn.Open();
      accessDBPSDriveInfo.Connection = conn;

      return accessDBPSDriveInfo;
    }

Di seguito è riportata la classe interna AccessDBPSDriveInfo che include il costruttore usato per creare una nuova unità e contiene le informazioni sullo stato per l'unità.

internal class AccessDBPSDriveInfo : PSDriveInfo
  {
    /// <summary>
    /// A reference to the connection to the database.
    /// </summary>
    private OdbcConnection connection;

    /// <summary>
    /// Initializes a new instance of the AccessDBPSDriveInfo class.
    /// The constructor takes a single argument.
    /// </summary>
    /// <param name="driveInfo">Drive defined by this provider</param>
    public AccessDBPSDriveInfo(PSDriveInfo driveInfo)
           : base(driveInfo)
    {
    }

    /// <summary>
    /// Gets or sets the ODBC connection information.
    /// </summary>
    public OdbcConnection Connection
    {
        get { return this.connection; }
        set { this.connection = value; }
    }
  }

Implementazione di RemoveDrive

Il metodo System.Management.Automation.Provider.Drivecmdletprovider.Removedrive* viene chiamato dal motore Windows PowerShell quando un utente chiama il cmdlet Microsoft.PowerShell.Commands.RemovePSDriveCommand. Il metodo in questo provider chiude la connessione al database di Access.

protected override PSDriveInfo RemoveDrive(PSDriveInfo drive)
    {
      // Check if drive object is null.
      if (drive == null)
      {
        WriteError(new ErrorRecord(
                   new ArgumentNullException("drive"),
                   "NullDrive",
                   ErrorCategory.InvalidArgument,
                   drive));

        return null;
      }

      // Close the ODBC connection to the drive.
      AccessDBPSDriveInfo accessDBPSDriveInfo = drive as AccessDBPSDriveInfo;

      if (accessDBPSDriveInfo == null)
      {
         return null;
      }

      accessDBPSDriveInfo.Connection.Close();

      return accessDBPSDriveInfo;
    }