Megosztás a következőn keresztül:


Parancsmag létrehozása adattár eléréséhez

Ez a szakasz bemutatja, hogyan hozhat létre olyan parancsmagokat, amelyek a tárolt adatokhoz férnek hozzá egy Windows PowerShell szolgáltatón keresztül. Ez a parancsmagtípus a Windows PowerShell-Windows PowerShell-es futtatás Windows PowerShell-szolgáltatói infrastruktúráját használja, ezért a parancsmag osztályának a System.Management.Automation.PSCmdlet alaposztályból kell származtatva lennie.

Az Select-Str ismertetett parancsmag megkeresheti és kiválaszthatja a sztringeket egy fájlban vagy objektumban. A sztring azonosításához használt minták explicit módon, a parancsmag paraméterén vagy implicit módon a paraméteren Path keresztül is Script meghatározhatóak.

A parancsmag úgy lett kialakítva, hogy a System.Management.Automation.Provider.IcontentcmdletproviderWindows PowerShell-szolgáltatót használja. A parancsmag például megadhatja a fájlrendszerszolgáltatót vagy a változószolgáltatót, amelyet a Windows PowerShell. További információ a Windows PowerShell-szolgáltatókról: Designing Your Windows PowerShell provider..

A parancsmagosztály meghatározása

A parancsmag létrehozásának első lépése mindig a parancsmag elnevezése és a parancsmagot megvalósító .NET-osztály deklarációja. Ez a parancsmag bizonyos sztringeket észlel, így az itt kiválasztott művelet neve "Select", amelyet a System.Management.Automation.Verbscommon osztály határoz meg. Az "Str" főnév azért használatos, mert a parancsmag sztringeket használ. Az alábbi deklarációban figyelje meg, hogy a parancsmag ige és főnév is megjelenik a parancsmagosztály nevében. A jóváhagyott parancsmagokkal kapcsolatos további információkért lásd: Parancsmagok parancsmagnevei.

A parancsmag .NET-osztályának a System.Management.Automation.PSCmdlet alaposztályból kell származtatva lennie, mivel biztosítja a Windows PowerShell-Windows PowerShell-futtatás számára az Windows PowerShell-szolgáltatói infrastruktúra elérhetővé Windows PowerShell támogatását. Vegye figyelembe, hogy ez a parancsmag a reguláris .NET-keretrendszer osztályokat is használja, például System.Text.Regularexpressions.Regex.

A következő kód a parancsmag osztálydefiníciója Select-Str parancsmaghoz.

[Cmdlet(VerbsCommon.Select, "Str", DefaultParameterSetName="PatternParameterSet")]
public class SelectStringCommand : PSCmdlet

Ez a parancsmag egy alapértelmezett paraméterkészletet határoz meg úgy, hogy hozzáadja az DefaultParameterSetName attribútum kulcsszót az osztálydeklarációhoz. Ha a paraméter nincs megadva, a rendszer az PatternParameterSet alapértelmezett Script paraméterkészletet használja. További információt erről a paraméterkészletről a következő szakaszban, a és a paraméter Pattern Script vitafórumában láthat.

Adatelérési paraméterek meghatározása

Ez a parancsmag számos olyan paramétert határoz meg, amelyek lehetővé teszik a felhasználó számára a tárolt adatokhoz való hozzáférést és vizsgálatokat. Ezek a paraméterek tartalmaznak egy paramétert, amely jelzi az adattár helyét, egy paramétert, amely meghatározza a keresésben használni szükséges mintát, valamint számos más paramétert, amely támogatja Path a Pattern keresések hajtható végre.

Megjegyzés

További információ a paraméterek meghatározásának alapjairól: Paraméterek hozzáadása parancssori bemenet feldolgozásához.

A Path paraméter deklarása

Az adattár megtalálásához a parancsmagnak egy Windows PowerShell elérési utat kell használnia az adattár eléréséhez tervezett Windows PowerShell-szolgáltató azonosításához. Ezért meghatároz egy sztringtömb típusú paramétert, amely Path jelzi a szolgáltató helyét.

[Parameter(
           Position = 0,
           ParameterSetName = "ScriptParameterSet",
           Mandatory = true)]
[Parameter(
           Position = 0,
           ParameterSetName = "PatternParameterSet",
           ValueFromPipeline = true,
           Mandatory = true)]
           [Alias("PSPath")]
public string[] Path
{
  get { return paths; }
  set { paths = value; }
}
private string[] paths;

Vegye figyelembe, hogy ez a paraméter két különböző paraméterkészlethez tartozik, és rendelkezik aliasokkal.

Két System.Management.Automation.Parameterattribute attribútum deklarálja, hogy a paraméter a és a Path ScriptParameterSet attribútumhoz PatternParameterSet tartozik. A paraméterkészletekkel kapcsolatos további információkért lásd: Adding Parameter Sets to a Cmdlet (Paraméterkészletek hozzáadása parancsmaghoz).

A System.Management.Automation.Aliasattribute attribútum deklarál egy aliast a PSPath Path paraméterhez. Az alias deklarált használata erősen ajánlott, hogy konzisztens legyen más, a Windows PowerShell parancsmagokkal. AWindows PowerShell-útvonalakkal kapcsolatos további információkért lásd a PowerShell elérésiút-fogalmakat a How Windows PowerShell Works (A PowerShell elérésiút-fogalmai) Windows PowerShell.

A mintaparaméter deklarása

A kereshető minták megadásához ez a parancsmag egy sztringek tömbjeként megadott Pattern paramétert deklarál. Pozitív eredményt ad vissza, ha a minták bármelyike megtalálható az adattárban. Vegye figyelembe, hogy ezek a minták lefordított reguláris kifejezések tömbjén vagy literális keresések helyettesítő karakteres mintái tömbjén fordíthatóak le.

[Parameter(
           Position = 1,
           ParameterSetName = "PatternParameterSet",
           Mandatory = true)]
public string[] Pattern
{
  get { return patterns; }
  set { patterns = value; }
}
private string[] patterns;
private Regex[] regexPattern;
private WildcardPattern[] wildcardPattern;

Ha ez a paraméter meg van adva, a parancsmag az alapértelmezett paraméterkészletet PatternParameterSet használja. Ebben az esetben a parancsmag az itt megadott mintákat használja a sztringek kiválasztásához. Ezzel szemben a paraméter is használható a mintákat tartalmazó Script szkriptek biztosítanak. A Script és paraméterek két külön Pattern paraméterkészletet határoznak meg, így kölcsönösen kizárják egymást.

Keresési támogatási paraméterek deklarása

Ez a parancsmag a következő támogatási paramétereket határozza meg, amelyek a parancsmag keresési képességeinek módosítására használhatók.

A paraméter megad egy szkriptblokkot, amely egy alternatív keresési mechanizmust biztosít Script a parancsmaghoz. A szkriptnek tartalmaznia kell az egyeztetéshez használt mintákat, és vissza kell adnunk egy System.Management.Automation.PSObject objektumot. Vegye figyelembe, hogy ez a paraméter az egyedi paraméter is, amely azonosítja ScriptParameterSet a paraméterkészletet. Amikor a Windows PowerShell látja ezt a paramétert, csak a paraméterkészlethez tartozó ScriptParameterSet paramétereket használja.

[Parameter(
           Position = 1,
           ParameterSetName = "ScriptParameterSet",
           Mandatory = true)]
public ScriptBlock Script
{
  set { script = value; }
  get { return script; }
}
ScriptBlock script;

A paraméter egy kapcsolóparaméter, amely azt jelzi, hogy a parancsmagnak pontosan meg kell-e egyeznie a megadott SimpleMatch mintákkal. Amikor a felhasználó megadja a paramétert a parancssorban ( ), a parancsmag a megadott true mintákat használja. Ha a paraméter nincs megadva ( ), a false parancsmag reguláris kifejezéseket használ. A paraméter alapértelmezett értéke false .

[Parameter]
public SwitchParameter SimpleMatch
{
  get { return simpleMatch; }
  set { simpleMatch = value; }
}
private bool simpleMatch;

A paraméter egy kapcsolóparaméter, amely azt jelzi, hogy CaseSensitive a kis- és nagybetűket megkülönböztető keresés történik-e. Amikor a felhasználó megadja a paramétert a parancssorban ( ), a parancsmag kis- és nagybetűs karaktereket keres a true minták összehasonlíthatóságakor. Ha a paraméter nincs megadva ( ), a parancsmag nem tesz különbséget false a kis- és nagybetűk között. Például a "MyFile" és a "myfile" is pozitív találatként lenne visszaadva. A paraméter alapértelmezett értéke false .

[Parameter]
public SwitchParameter CaseSensitive
{
  get { return caseSensitive; }
  set { caseSensitive = value; }
}
private bool caseSensitive;

A és a paraméter azonosítja azokat az elemeket, amelyek kifejezetten ki vannak zárva a keresésből, vagy Exclude Include amelyek szerepelnek a keresésben. Alapértelmezés szerint a parancsmag az adattár összes elemében keres. A parancsmag által végzett keresés korlátozására azonban ezek a paraméterek használhatók a keresésbe foglalni vagy kihagyni szükséges elemek explicit jelzésére.

[Parameter]
public SwitchParameter CaseSensitive
{
  get { return caseSensitive; }
  set { caseSensitive = value; }
}
private bool caseSensitive;
[Parameter]
[ValidateNotNullOrEmpty]
public string[] Include
{
  get
  {
    return includeStrings;
  }
  set
  {
    includeStrings = value;

    this.include = new WildcardPattern[includeStrings.Length];
    for (int i = 0; i < includeStrings.Length; i++)
    {
      this.include[i] = new WildcardPattern(includeStrings[i], WildcardOptions.IgnoreCase);
    }
  }
}

internal string[] includeStrings = null;
internal WildcardPattern[] include = null;

Paraméterkészletek deklarása

Ez a parancsmag két paraméterkészletet használ ( és , amely az alapértelmezett beállítás) az adatelérésben használt két ScriptParameterSet PatternParameterSet paraméterkészlet neveként. PatternParameterSet A az alapértelmezett paraméterkészlet, és a paraméter megadásakor Pattern lesz használva. ScriptParameterSet Akkor használatos, ha a felhasználó alternatív keresési mechanizmust ad meg a Script paraméterrel. A paraméterkészletekkel kapcsolatos további információkért lásd: Adding Parameter Sets to a Cmdlet (Paraméterkészletek hozzáadása parancsmaghoz).

A bemeneti feldolgozási módszerek felülbírálása

A parancsmagok a System.Management.Automation.PSCmdlet osztály egy vagy több bemeneti feldolgozási metódusát felül kell bírálni. A bemeneti feldolgozási metódusokkal kapcsolatos további információkért lásd: Creating Your First Cmdlet (Az első parancsmag létrehozása).

Ez a parancsmag felülírja a System.Management.Automation.Cmdlet.BeginProcessing metódust, hogy lefordított reguláris kifejezések tömbje indításakor létre legyen hozva. Ez növeli a teljesítményt olyan keresések során, amelyek nem egyszerű egyeztetést használnak.

protected override void BeginProcessing()
{
  WriteDebug("Validating patterns.");
  if (patterns != null)
  {
    foreach(string pattern in patterns)
    {
      if (pattern == null)
      ThrowTerminatingError(new ErrorRecord(
                            new ArgumentNullException(
                            "Search pattern cannot be null."),
                            "NullSearchPattern",
                            ErrorCategory.InvalidArgument,
                            pattern)
                            );
    }

    WriteVerbose("Search pattern(s) are valid.");

    // If a simple match is not specified, then
    // compile the regular expressions once.
    if (!simpleMatch)
    {
      WriteDebug("Compiling search regular expressions.");

      RegexOptions regexOptions = RegexOptions.Compiled;
      if (!caseSensitive)
         regexOptions |= RegexOptions.Compiled;
      regexPattern = new Regex[patterns.Length];

      for (int i = 0; i < patterns.Length; i++)
      {
        try
        {
          regexPattern[i] = new Regex(patterns[i], regexOptions);
        }
        catch (ArgumentException ex)
        {
          ThrowTerminatingError(new ErrorRecord(
                        ex,
                        "InvalidRegularExpression",
                        ErrorCategory.InvalidArgument,
                        patterns[i]
                     ));
        }
      } //Loop through patterns to create RegEx objects.

      WriteVerbose("Pattern(s) compiled into regular expressions.");
    }// If not a simple match.

    // If a simple match is specified, then compile the
    // wildcard patterns once.
    else
    {
      WriteDebug("Compiling search wildcards.");

      WildcardOptions wildcardOptions = WildcardOptions.Compiled;

      if (!caseSensitive)
      {
        wildcardOptions |= WildcardOptions.IgnoreCase;
      }

      wildcardPattern = new WildcardPattern[patterns.Length];
      for (int i = 0; i < patterns.Length; i++)
      {
        wildcardPattern[i] =
                     new WildcardPattern(patterns[i], wildcardOptions);
      }

      WriteVerbose("Pattern(s) compiled into wildcard expressions.");
    }// If match is a simple match.
  }// If valid patterns are available.
}// End of function BeginProcessing().

Ez a parancsmag felülbírálja a System.Management.Automation.Cmdlet.ProcessRecord metódust is a felhasználó által a parancssorban kiválasztott sztringek feldolgozásához. Egyéni objektum formájában írja a sztringkiválasztás eredményeit egy privát MatchString metódus hívásával.

protected override void ProcessRecord()
{
  UInt64 lineNumber = 0;
  MatchInfo result;
  ArrayList nonMatches = new ArrayList();

  // Walk the list of paths and search the contents for
  // any of the specified patterns.
  foreach (string psPath in paths)
  {
    // Once the filepaths are expanded, we may have more than one
    // path, so process all referenced paths.
    foreach(PathInfo path in
            SessionState.Path.GetResolvedPSPathFromPSPath(psPath)
           )
    {
      WriteVerbose("Processing path " + path.Path);

      // Check if the path represents one of the items to be
      // excluded. If so, continue to next path.
      if (!MeetsIncludeExcludeCriteria(path.ProviderPath))
         continue;

      // Get the content reader for the item(s) at the
      // specified path.
      Collection<IContentReader> readerCollection = null;
      try
      {
        readerCollection =
                    this.InvokeProvider.Content.GetReader(path.Path);
      }
      catch (PSNotSupportedException ex)
      {
        WriteError(new ErrorRecord(ex,
                   "ContentAccessNotSupported",
                    ErrorCategory.NotImplemented,
                    path.Path)
                   );
        return;
      }

      foreach(IContentReader reader in readerCollection)
      {
        // Reset the line number for this path.
        lineNumber = 0;

        // Read in a single block (line in case of a file)
        // from the object.
        IList items = reader.Read(1);

        // Read and process one block(line) at a time until
        // no more blocks(lines) exist.
        while (items != null && items.Count == 1)
        {
          // Increment the line number each time a line is
          // processed.
          lineNumber++;

          String message = String.Format("Testing line {0} : {1}",
                                        lineNumber, items[0]);

          WriteDebug(message);

          result = SelectString(items[0]);

          if (result != null)
          {
            result.Path = path.Path;
            result.LineNumber = lineNumber;

            WriteObject(result);
          }
          else
          {
            // Add the block(line) that did not match to the
            // collection of non matches , which will be stored
            // in the SessionState variable $NonMatches
            nonMatches.Add(items[0]);
          }

          // Get the next line from the object.
          items = reader.Read(1);

        }// While loop for reading one line at a time.
      }// Foreach loop for reader collection.
    }// Foreach loop for processing referenced paths.
  }// Foreach loop for walking of path list.

  // Store the list of non-matches in the
  // session state variable $NonMatches.
  try
  {
    this.SessionState.PSVariable.Set("NonMatches", nonMatches);
  }
  catch (SessionStateUnauthorizedAccessException ex)
  {
    WriteError(new ErrorRecord(ex,
               "CannotWriteVariableNonMatches",
               ErrorCategory.InvalidOperation,
               nonMatches)
              );
  }

}// End of protected override void ProcessRecord().

Tartalom elérése

A parancsmagnak meg kell nyitnia a Windows PowerShell által jelzett szolgáltatót, hogy hozzáfér az adatokhoz. A rendszer a runspace System.Management.Automation.Sessionstate objektumát használja a szolgáltatóhoz való hozzáféréshez, a parancsmag System.Management.Automation.PSCmdlet.Invokeprovider* tulajdonsága pedig a szolgáltató megnyitásához. A tartalomhoz való hozzáférést a megnyitott szolgáltató System.Management.Automation.Providerintrinsics objektumának lekérése biztosítja.

Ez a Select-Str parancsmag a System.Management.Automation.Providerintrinsics.Content* tulajdonság segítségével teszi elérhetővé a vizsgálható tartalmat. Ezután meg tudja hívni a System.Management.Automation.Contentcmdletproviderintrinsics.Getreader* metódust, és át tudja adni a Windows PowerShell elérési útját.

Kódminta

Az alábbi kód a parancsmag ezen verziójának megvalósítását Select-Str be. Vegye figyelembe, hogy ez a kód tartalmazza a parancsmag osztályát, a parancsmag által használt privát metódusokat, valamint a Windows PowerShell regisztráláshoz használt beépülő modul kódját. További információ a parancsmag regisztrálásról: Building the Cmdlet.

//
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
using System;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Provider;
using System.ComponentModel;

namespace Microsoft.Samples.PowerShell.Commands
{
  #region SelectStringCommand
  /// <summary>
  /// This cmdlet searches through PSObjects for particular patterns.
  /// </summary>
  /// <remarks>
  /// This cmdlet can be used to search any object, such as a file or a
  /// variable, whose provider exposes methods for reading and writing
  /// content.
  /// </remarks>
  [Cmdlet(VerbsCommon.Select, "Str", DefaultParameterSetName="PatternParameterSet")]
  public class SelectStringCommand : PSCmdlet
  {
    #region Parameters
    /// <summary>
    /// Declare a Path parameter that specifies where the data is stored.
    /// This parameter must specify a PowerShell that indicates the
    /// PowerShell provider that is used to access the objects to be
    /// searched for matching patterns. This parameter should also have
    /// a PSPath alias to provide consistency with other cmdlets that use
    /// PowerShell providers.
    /// </summary>
    /// <value>Path of the object(s) to search.</value>
    [Parameter(
               Position = 0,
               ParameterSetName = "ScriptParameterSet",
               Mandatory = true)]
    [Parameter(
               Position = 0,
               ParameterSetName = "PatternParameterSet",
               ValueFromPipeline = true,
               Mandatory = true)]
               [Alias("PSPath")]
    public string[] Path
    {
      get { return paths; }
      set { paths = value; }
    }
    private string[] paths;

    /// <summary>
    /// Declare a Pattern parameter that specifies the pattern(s)
    /// used to find matching patterns in the string representation
    /// of the objects. A positive result will be returned
    /// if any of the patterns are found in the objects.
    /// </summary>
    /// <remarks>
    /// The patterns will be compiled into an array of wildcard
    /// patterns for a simple match (literal string matching),
    /// or the patterns will be converted into an array of compiled
    /// regular expressions.
    /// </remarks>
    /// <value>Array of patterns to search.</value>
    [Parameter(
               Position = 1,
               ParameterSetName = "PatternParameterSet",
               Mandatory = true)]
    public string[] Pattern
    {
      get { return patterns; }
      set { patterns = value; }
    }
    private string[] patterns;
    private Regex[] regexPattern;
    private WildcardPattern[] wildcardPattern;

    /// <summary>
    /// Declare a Script parameter that specifies a script block
    /// that is called to perform the matching operations
    /// instead of the matching performed by the cmdlet.
    /// </summary>
    /// <value>Script block that will be called for matching</value>
    [Parameter(
               Position = 1,
               ParameterSetName = "ScriptParameterSet",
               Mandatory = true)]
    public ScriptBlock Script
    {
      set { script = value; }
      get { return script; }
    }
    ScriptBlock script;

    /// <summary>
    /// Declare a switch parameter that specifies if the pattern(s) are used
    /// literally. If not (default), searching is
    /// done using regular expressions.
    /// </summary>
    /// <value>If True, a literal pattern is used.</value>
    [Parameter]
    public SwitchParameter SimpleMatch
    {
      get { return simpleMatch; }
      set { simpleMatch = value; }
    }
    private bool simpleMatch;

    /// <summary>
    /// Declare a switch parameter that specifies if a case-sensitive
    /// search is performed.  If not (default), a case-insensitive search
    /// is performed.
    /// </summary>
    /// <value>If True, a case-sensitive search is made.</value>
    [Parameter]
    public SwitchParameter CaseSensitive
    {
      get { return caseSensitive; }
      set { caseSensitive = value; }
    }
    private bool caseSensitive;

    /// <summary>
    /// Declare an Include parameter that species which
    /// specific items are searched.  When this parameter
    /// is used, items that are not listed here are omitted
    /// from the search.
    /// </summary>
    [Parameter]
    [ValidateNotNullOrEmpty]
    public string[] Include
    {
      get
      {
        return includeStrings;
      }
      set
      {
        includeStrings = value;

        this.include = new WildcardPattern[includeStrings.Length];
        for (int i = 0; i < includeStrings.Length; i++)
        {
          this.include[i] = new WildcardPattern(includeStrings[i], WildcardOptions.IgnoreCase);
        }
      }
    }

    internal string[] includeStrings = null;
    internal WildcardPattern[] include = null;

    /// <summary>
    /// Declare an Exclude parameter that species which
    /// specific items are omitted from the search.
    /// </summary>
    ///
    [Parameter]
    [ValidateNotNullOrEmpty]
    public string[] Exclude
    {
      get
      {
        return excludeStrings;
      }
      set
      {
        excludeStrings = value;

        this.exclude = new WildcardPattern[excludeStrings.Length];
        for (int i = 0; i < excludeStrings.Length; i++)
        {
          this.exclude[i] = new WildcardPattern(excludeStrings[i], WildcardOptions.IgnoreCase);
        }
      }
    }
    internal string[] excludeStrings;
    internal WildcardPattern[] exclude;

    #endregion Parameters

    #region Overrides
    /// <summary>
    /// If regular expressions are used for pattern matching,
    /// then build an array of compiled regular expressions
    /// at startup. This increases performance during scanning
    /// operations when simple matching is not used.
    /// </summary>
    protected override void BeginProcessing()
    {
      WriteDebug("Validating patterns.");
      if (patterns != null)
      {
        foreach(string pattern in patterns)
        {
          if (pattern == null)
          ThrowTerminatingError(new ErrorRecord(
                                new ArgumentNullException(
                                "Search pattern cannot be null."),
                                "NullSearchPattern",
                                ErrorCategory.InvalidArgument,
                                pattern)
                                );
        }

        WriteVerbose("Search pattern(s) are valid.");

        // If a simple match is not specified, then
        // compile the regular expressions once.
        if (!simpleMatch)
        {
          WriteDebug("Compiling search regular expressions.");

          RegexOptions regexOptions = RegexOptions.Compiled;
          if (!caseSensitive)
             regexOptions |= RegexOptions.Compiled;
          regexPattern = new Regex[patterns.Length];

          for (int i = 0; i < patterns.Length; i++)
          {
            try
            {
              regexPattern[i] = new Regex(patterns[i], regexOptions);
            }
            catch (ArgumentException ex)
            {
              ThrowTerminatingError(new ErrorRecord(
                            ex,
                            "InvalidRegularExpression",
                            ErrorCategory.InvalidArgument,
                            patterns[i]
                         ));
            }
          } //Loop through patterns to create RegEx objects.

          WriteVerbose("Pattern(s) compiled into regular expressions.");
        }// If not a simple match.

        // If a simple match is specified, then compile the
        // wildcard patterns once.
        else
        {
          WriteDebug("Compiling search wildcards.");

          WildcardOptions wildcardOptions = WildcardOptions.Compiled;

          if (!caseSensitive)
          {
            wildcardOptions |= WildcardOptions.IgnoreCase;
          }

          wildcardPattern = new WildcardPattern[patterns.Length];
          for (int i = 0; i < patterns.Length; i++)
          {
            wildcardPattern[i] =
                         new WildcardPattern(patterns[i], wildcardOptions);
          }

          WriteVerbose("Pattern(s) compiled into wildcard expressions.");
        }// If match is a simple match.
      }// If valid patterns are available.
    }// End of function BeginProcessing().

    /// <summary>
    /// Process the input and search for the specified patterns.
    /// </summary>
    protected override void ProcessRecord()
    {
      UInt64 lineNumber = 0;
      MatchInfo result;
      ArrayList nonMatches = new ArrayList();

      // Walk the list of paths and search the contents for
      // any of the specified patterns.
      foreach (string psPath in paths)
      {
        // Once the filepaths are expanded, we may have more than one
        // path, so process all referenced paths.
        foreach(PathInfo path in
                SessionState.Path.GetResolvedPSPathFromPSPath(psPath)
               )
        {
          WriteVerbose("Processing path " + path.Path);

          // Check if the path represents one of the items to be
          // excluded. If so, continue to next path.
          if (!MeetsIncludeExcludeCriteria(path.ProviderPath))
             continue;

          // Get the content reader for the item(s) at the
          // specified path.
          Collection<IContentReader> readerCollection = null;
          try
          {
            readerCollection =
                        this.InvokeProvider.Content.GetReader(path.Path);
          }
          catch (PSNotSupportedException ex)
          {
            WriteError(new ErrorRecord(ex,
                       "ContentAccessNotSupported",
                        ErrorCategory.NotImplemented,
                        path.Path)
                       );
            return;
          }

          foreach(IContentReader reader in readerCollection)
          {
            // Reset the line number for this path.
            lineNumber = 0;

            // Read in a single block (line in case of a file)
            // from the object.
            IList items = reader.Read(1);

            // Read and process one block(line) at a time until
            // no more blocks(lines) exist.
            while (items != null && items.Count == 1)
            {
              // Increment the line number each time a line is
              // processed.
              lineNumber++;

              String message = String.Format("Testing line {0} : {1}",
                                            lineNumber, items[0]);

              WriteDebug(message);

              result = SelectString(items[0]);

              if (result != null)
              {
                result.Path = path.Path;
                result.LineNumber = lineNumber;

                WriteObject(result);
              }
              else
              {
                // Add the block(line) that did not match to the
                // collection of non matches , which will be stored
                // in the SessionState variable $NonMatches
                nonMatches.Add(items[0]);
              }

              // Get the next line from the object.
              items = reader.Read(1);

            }// While loop for reading one line at a time.
          }// Foreach loop for reader collection.
        }// Foreach loop for processing referenced paths.
      }// Foreach loop for walking of path list.

      // Store the list of non-matches in the
      // session state variable $NonMatches.
      try
      {
        this.SessionState.PSVariable.Set("NonMatches", nonMatches);
      }
      catch (SessionStateUnauthorizedAccessException ex)
      {
        WriteError(new ErrorRecord(ex,
                   "CannotWriteVariableNonMatches",
                   ErrorCategory.InvalidOperation,
                   nonMatches)
                  );
      }

    }// End of protected override void ProcessRecord().
    #endregion Overrides

    #region PrivateMethods
    /// <summary>
    /// Check for a match using the input string and the pattern(s)
    /// specified.
    /// </summary>
    /// <param name="input">The string to test.</param>
    /// <returns>MatchInfo object containing information about
    /// result of a match</returns>
    private MatchInfo SelectString(object input)
    {
      string line = null;

      try
      {
        // Convert the object to a string type
        // safely using language support methods
        line = (string)LanguagePrimitives.ConvertTo(
                                                    input,
                                                    typeof(string)
                                                    );
        line = line.Trim(' ','\t');
      }
      catch (PSInvalidCastException ex)
      {
        WriteError(new ErrorRecord(
                   ex,
                   "CannotCastObjectToString",
                   ErrorCategory.InvalidOperation,
                   input)
                   );

        return null;
      }

      MatchInfo result = null;

      // If a scriptblock has been specified, call it
      // with the path for processing.  It will return
      // one object.
      if (script != null)
      {
        WriteDebug("Executing script block.");

        Collection<PSObject> psObjects =
                             script.Invoke(
                                           line,
                                           simpleMatch,
                                           caseSensitive
                                          );

        foreach (PSObject psObject in psObjects)
        {
          if (LanguagePrimitives.IsTrue(psObject))
          {
            result = new MatchInfo();
            result.Line = line;
            result.IgnoreCase = !caseSensitive;

            break;
          } //End of If.
        } //End ForEach loop.
      } // End of If if script exists.

      // If script block exists, see if this line matches any
      // of the match patterns.
      else
      {
        int patternIndex = 0;

        while (patternIndex < patterns.Length)
        {
          if ((simpleMatch &&
              wildcardPattern[patternIndex].IsMatch(line))
              || (regexPattern != null
              && regexPattern[patternIndex].IsMatch(line))
             )
          {
            result = new MatchInfo();
            result.IgnoreCase = !caseSensitive;
            result.Line = line;
            result.Pattern = patterns[patternIndex];

            break;
          }

          patternIndex++;

        }// While loop through patterns.
      }// Else for no script block specified.

      return result;

    }// End of SelectString

    /// <summary>
    /// Check whether the supplied name meets the include/exclude criteria.
    /// That is - it's on the include list if the include list was
    /// specified, and not on the exclude list if the exclude list was specified.
    /// </summary>
    /// <param name="path">path to validate</param>
    /// <returns>True if the path is acceptable.</returns>
    private bool MeetsIncludeExcludeCriteria(string path)
    {
      bool ok = false;

      // See if the file is on the include list.
      if (this.include != null)
      {
        foreach (WildcardPattern patternItem in this.include)
        {
          if (patternItem.IsMatch(path))
          {
            ok = true;
            break;
          }
        }
      }
      else
      {
        ok = true;
      }

      if (!ok)
         return false;

      // See if the file is on the exclude list.
      if (this.exclude != null)
      {
        foreach (WildcardPattern patternItem in this.exclude)
        {
          if (patternItem.IsMatch(path))
          {
            ok = false;
            break;
          }
        }
      }

      return ok;
    } //MeetsIncludeExcludeCriteria
    #endregion Private Methods

  }// class SelectStringCommand

  #endregion SelectStringCommand

  #region MatchInfo

  /// <summary>
  /// Class representing the result of a pattern/literal match
  /// that is passed through the pipeline by the Select-Str cmdlet.
  /// </summary>
  public class MatchInfo
  {
    /// <summary>
    /// Indicates if the match was done ignoring case.
    /// </summary>
    /// <value>True if case was ignored.</value>
    public bool IgnoreCase
    {
      get { return ignoreCase; }
      set { ignoreCase = value; }
    }
    private bool ignoreCase;

    /// <summary>
    /// Specifies the number of the matching line.
    /// </summary>
    /// <value>The number of the matching line.</value>
    public UInt64 LineNumber
    {
      get { return lineNumber; }
      set { lineNumber = value; }
    }
    private UInt64 lineNumber;

    /// <summary>
    /// Specifies the text of the matching line.
    /// </summary>
    /// <value>The text of the matching line.</value>
    public string Line
    {
      get { return line; }
      set { line = value; }
    }
    private string line;

    /// <summary>
    /// Specifies the full path of the object(file) containing the
    /// matching line.
    /// </summary>
    /// <remarks>
    /// It will be "inputStream" if the object came from the input
    /// stream.
    /// </remarks>
    /// <value>The path name</value>
    public string Path
    {
      get { return path; }
      set
      {
        pathSet = true;
        path = value;
      }
    }
    private string path;
    private bool pathSet;

    /// <summary>
    /// Specifies the pattern that was used in the match.
    /// </summary>
    /// <value>The pattern string</value>
    public string Pattern
    {
      get { return pattern; }
      set { pattern = value; }
    }
    private string pattern;

    private const string MatchFormat = "{0}:{1}:{2}";

    /// <summary>
    /// Returns the string representation of this object. The format
    /// depends on whether a path has been set for this object or
    /// not.
    /// </summary>
    /// <remarks>
    /// If the path component is set, as would be the case when
    /// matching in a file, ToString() returns the path, line
    /// number and line text.  If path is not set, then just the
    /// line text is presented.
    /// </remarks>
    /// <returns>The string representation of the match object.</returns>
    public override string ToString()
    {
      if (pathSet)
         return String.Format(
         System.Threading.Thread.CurrentThread.CurrentCulture,
         MatchFormat,
         this.path,
         this.lineNumber,
         this.line
         );
      else
         return this.line;
    }
  }// End class MatchInfo

  #endregion

  #region PowerShell snap-in

  /// <summary>
  /// Create a PowerShell snap-in for the Select-Str cmdlet.
  /// </summary>
  [RunInstaller(true)]
  public class SelectStringPSSnapIn : PSSnapIn
  {
    /// <summary>
    /// Create an instance of the SelectStrPSSnapin class.
    /// </summary>
    public SelectStringPSSnapIn()
           : base()
    {
    }

    /// <summary>
    /// Specify the name of the PowerShell snap-in.
    /// </summary>
    public override string Name
    {
      get
      {
        return "SelectStrPSSnapIn";
      }
    }

    /// <summary>
    /// Specify the vendor of the PowerShell snap-in.
    /// </summary>
    public override string Vendor
    {
      get
      {
        return "Microsoft";
      }
    }

    /// <summary>
    /// Specify the localization resource information for the vendor.
    /// Use the format: SnapinName,VendorName.
    /// </summary>
    public override string VendorResource
    {
      get
      {
        return "SelectStrSnapIn,Microsoft";
      }
    }

    /// <summary>
    /// Specify the description of the PowerShell snap-in.
    /// </summary>
    public override string Description
    {
      get
        {
          return "This is a PowerShell snap-in for the Select-Str cmdlet.";
        }
    }

    /// <summary>
    /// Specify the localization resource information for the description.
    /// Use the format: SnapinName,Description.

    /// </summary>
    public override string DescriptionResource
    {
      get
      {
          return "SelectStrSnapIn,This is a PowerShell snap-in for the Select-Str cmdlet.";
      }
    }
  }
  #endregion PowerShell snap-in

} //namespace Microsoft.Samples.PowerShell.Commands;

A parancsmag kiépítése

A parancsmagok megvalósítása után regisztrálnia kell azt a Windows PowerShell egy Windows PowerShell beépülő modulon keresztül. További információ a parancsmagok regisztrálásról: How to Register Cmdlets, Providers, and Host Applications (Parancsmagok, szolgáltatók és gazdaalkalmazások regisztrálása).

A parancsmag tesztelése

Miután regisztrálta a parancsmagot a Windows PowerShell, a parancssorban futtatva tesztelheti. Az alábbi eljárással tesztelheti a Select-Str parancsmagot.

  1. Indítsa Windows PowerShell, majd keresse meg a Notes fájlban a ".NET" kifejezéssel kiegészítve a sorok előfordulásait. Vegye figyelembe, hogy az elérési út neve körüli idézőjelek csak akkor szükségesek, ha az elérési út egynél több szóból áll.

    select-str -Path "notes" -Pattern ".NET" -SimpleMatch=$false
    

    Az alábbi kimenet jelenik meg.

    IgnoreCase   : True
    LineNumber   : 8
    Line         : Because Windows PowerShell works directly with .NET objects, there is often a .NET object
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes
    Pattern      : .NET
    IgnoreCase   : True
    LineNumber   : 21
    Line         : You should normally define the class for a cmdlet in a .NET namespace
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes
    Pattern      : .NET
    
  2. A Notes fájlban keressen sorokat az "over" szóval, majd bármely más szöveggel együtt. A SimpleMatch paraméter az alapértelmezett értéket false használja. A keresés nemérzékeny, mert a paraméter értéke CaseSensitive false .

    select-str -Path notes -Pattern "over*" -SimpleMatch -CaseSensitive:$false
    

    Az alábbi kimenet jelenik meg.

    IgnoreCase   : True
    LineNumber   : 45
    Line         : Override StopProcessing
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes
    Pattern      : over*
    IgnoreCase   : True
    LineNumber   : 49
    Line         : overriding the StopProcessing method
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes
    Pattern      : over*
    
  3. Keressen a Notes fájlban egy reguláris kifejezés mintájaként. A parancsmag betűrendbe szedett karaktereket és zárójelek közötti üres szóközöket keres.

    select-str -Path notes -Pattern "\([A-Za-z:blank:]" -SimpleMatch:$false
    

    Az alábbi kimenet jelenik meg.

    IgnoreCase   : True
    LineNumber   : 1
    Line         : Advisory Guidelines (Consider Following)
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes
    Pattern      : \([A-Za-z:blank:]
    IgnoreCase   : True
    LineNumber   : 53
    Line         : If your cmdlet has objects that are not disposed of (written to the pipeline)
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes
    Pattern      : \([A-Za-z:blank:]
    
  4. Végezzen megkülönbözteti a kis- és nagybetűket a Notes fájlban, és keressen rá a "Parameter" szó előfordulásaira.

    select-str -Path notes -Pattern Parameter -CaseSensitive
    

    Az alábbi kimenet jelenik meg.

    IgnoreCase   : False
    LineNumber   : 6
    Line         : Support an InputObject Parameter
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes
    Pattern      : Parameter
    IgnoreCase   : False
    LineNumber   : 30
    Line         : Support Force Parameter
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes
    Pattern      : Parameter
    
  5. Keresse meg a változókhoz Windows PowerShell változókat, amelyek 0 és 9 között numerikus értékeket tartalmaznak.

    select-str -Path * -Pattern "[0-9]"
    

    Az alábbi kimenet jelenik meg.

    IgnoreCase   : True
    LineNumber   : 1
    Line         : 64
    Path         : Variable:\MaximumHistoryCount
    Pattern      : [0-9]
    
  6. Egy szkriptblokk használatával keressen a SelectStrCommandSample.cs fájlban a "Pos" sztringre. A szkript cmatch függvénye a kis- és a nagy- és a kis- és a nagy- és a nagy- és a kis- és a nagy- és kis- és a nagy

    select-str -Path "SelectStrCommandSample.cs" -Script { if ($args[0] -cmatch "Pos"){ return $true } return $false }
    

    Az alábbi kimenet jelenik meg.

    IgnoreCase   : True
    LineNumber   : 37
    Line         :    Position = 0.
    Path         : C:\PowerShell-Progs\workspace\Samples\SelectStr\SelectStrCommandSample.cs
    Pattern      :
    

Lásd még:

Új parancsmag Windows PowerShell létrehozása

Az első parancsmag létrehozása

Rendszermódosító parancsmag létrehozása

Saját Windows PowerShell megtervezése

Az Windows PowerShell működése

Parancsmagok, szolgáltatók és gazdaalkalmazások regisztrálása

Windows PowerShell SDK