Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a szakasz azt ismerteti, hogyan hozhat létre olyan parancsmagot, amely Windows PowerShell-szolgáltatón keresztül fér hozzá a tárolt adatokhoz. Ez a parancsmagtípus a Windows PowerShell-futtatókörnyezet Windows PowerShell-szolgáltatói infrastruktúráját használja, ezért a parancsmagosztálynak a System.Management.Automation.PSCmdlet alaposztályból kell származnia.
Az itt ismertetett Select-Str parancsmag megkeresheti és kijelölheti a sztringeket egy fájlban vagy objektumban. A sztring azonosításához használt minták explicit módon, a parancsmag Path paraméterén keresztül vagy implicit módon, a Script paraméteren keresztül határozhatók meg.
A parancsmag a System.Management.Automation.Provider.IContentCmdletProvider . A parancsmag például megadhatja a Windows PowerShell által biztosított Fájlrendszer-szolgáltatót vagy változószolgáltatót. További információ aWindows PowerShell-szolgáltatókról: A Windows PowerShell-szolgáltató tervezése.
A parancsmagosztály definiálása
A parancsmag létrehozásának első lépése mindig a parancsmag elnevezése és a parancsmagot implementáló .NET-osztály deklarálása. Ez a parancsmag bizonyos sztringeket észlel, ezért az itt kiválasztott ige neve "Kiválasztás", amelyet a System.Management.Automation.VerbsCommon osztály határoz meg. Az "Str" főnév azért használatos, mert a parancsmag sztringekre hat. Az alábbi deklarációban vegye figyelembe, hogy a parancsmag és a főnév neve megjelenik a parancsmagosztály nevében. A jóváhagyott parancsmag-parancsmagokkal kapcsolatos további információkért lásd parancsmagok parancsmagjának nevei.
A parancsmag .NET-osztályának a System.Management.Automation.PSCmdlet alaposztályból kell származnia, mivel biztosítja a Windows PowerShell-futtatókörnyezet által a Windows PowerShell-szolgáltató infrastruktúrájának elérhetővé tétele érdekében szükséges támogatást. Vegye figyelembe, hogy ez a parancsmag a .NET-keretrendszer reguláris kifejezésosztályait is használja, például System.Text.RegularExpressions.Regex.
A következő kód a Select-Str parancsmag osztálydefiníciója.
[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 a DefaultParameterSetName attribútum kulcsszót az osztálydeklarációhoz. Az alapértelmezett paraméterkészlet PatternParameterSet akkor használatos, ha a Script paraméter nincs megadva. A paraméterkészlettel kapcsolatos további információkért tekintse meg a következő szakaszban található Pattern és Script paraméterbeszélgetést.
Az adathozzáférés paramétereinek meghatározása
Ez a parancsmag több paramétert határoz meg, amelyek lehetővé teszik a felhasználó számára a tárolt adatok elérését és vizsgálatát. Ezek a paraméterek egy Path paramétert tartalmaznak, amely az adattár helyét jelzi, egy Pattern paramétert, amely meghatározza a keresésben használni kívánt mintát, valamint számos egyéb paramétert, amelyek támogatják a keresés végrehajtását.
Megjegyzés
További információ a paraméterek definiálásának alapjairól: [Parancssori bemenetet feldolgozó paraméterek hozzáadása][04].
Az elérésiút-paraméter deklarálása
Az adattár megkereséséhez ennek a parancsmagnak Windows PowerShell-elérési út használatával kell azonosítania az adattárhoz való hozzáférésre tervezett Windows PowerShell-szolgáltatót. Ezért egy Path típusú sztringtömb paraméterét határozza meg a szolgáltató helyének jelzésére.
[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 aliasa van.
Két System.Management.Automation.ParameterAttribute attribútum deklarálja, hogy a Path paraméter a ScriptParameterSet és a PatternParameterSettartozik. További információ a paraméterkészletekről: Paraméterkészletek hozzáadása parancsmaghoz.
A System.Management.Automation.AliasAttribute attribútum deklarál egy PSPath aliast a Path paraméterhez. Az alias deklarálása erősen ajánlott a Windows PowerShell-szolgáltatókhoz hozzáférő más parancsmagokkal való konzisztenciához. További információ aWindows PowerShell-elérési utakról: "PowerShell path concepts" in How Windows PowerShell Works.
A mintaparaméter deklarálása
A keresendő minták megadásához ez a parancsmag deklarál egy Pattern paramétert, amely sztringek tömbje. A rendszer pozitív eredményt ad vissza, ha bármelyik minta megtalálható az adattárban. Vegye figyelembe, hogy ezek a minták lefordíthatók lefordított reguláris kifejezések tömbjeibe vagy a literális keresésekhez használt helyettesítő karakterekből álló tömbbe.
[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;
A paraméter megadásakor a parancsmag az alapértelmezett PatternParameterSetparaméterkészletet használja.
Ebben az esetben a parancsmag az itt megadott mintákat használja a sztringek kiválasztásához. Ezzel szemben a Script paraméter használható a mintákat tartalmazó szkriptek megadására is. A Script és Pattern paraméterek két külön paraméterkészletet határoznak meg, így kölcsönösen kizárják egymást.
Keresési támogatási paraméterek deklarálá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 Script paraméter egy szkriptblokkot határoz meg, amely a parancsmag alternatív keresési mechanizmusának biztosítására használható. A szkriptnek tartalmaznia kell az egyezéshez használt mintákat, és vissza kell adnia egy System.Management.Automation.PSObject objektumot. Vegye figyelembe, hogy ez a paraméter az ScriptParameterSet paraméterkészletet azonosító egyedi paraméter is. Amikor a Windows PowerShell-futtatókörnyezet ezt a paramétert látja, csak a ScriptParameterSet paraméterkészlethez tartozó paramétereket használja.
[Parameter(
Position = 1,
ParameterSetName = "ScriptParameterSet",
Mandatory = true)]
public ScriptBlock Script
{
set { script = value; }
get { return script; }
}
ScriptBlock script;
A SimpleMatch paraméter egy kapcsolóparaméter, amely jelzi, hogy a parancsmagnak explicit módon meg kell-e egyeznie a megadott mintákkal. Amikor a felhasználó megadja a paramétert a parancssorban (true), a parancsmag a megadott mintákat használja. Ha a paraméter nincs megadva (false), a parancsmag normál kifejezéseket használ. Ennek a paraméternek az alapértelmezett értéke false.
[Parameter]
public SwitchParameter SimpleMatch
{
get { return simpleMatch; }
set { simpleMatch = value; }
}
private bool simpleMatch;
A CaseSensitive paraméter egy kapcsolóparaméter, amely jelzi, hogy 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 (true), a parancsmag a minták összehasonlításakor ellenőrzi a kis- és nagybetűket. Ha a paraméter nincs megadva (false), a parancsmag nem tesz különbséget a nagybetűk és a kisbetűk között. Például a "MyFile" és a "myfile" is pozitív találatként lesz visszaadva. Ennek a paraméternek az alapértelmezett értéke false.
[Parameter]
public SwitchParameter CaseSensitive
{
get { return caseSensitive; }
set { caseSensitive = value; }
}
private bool caseSensitive;
A Exclude és Include paraméterek olyan elemeket azonosítanak, amelyek kifejezetten kizártak vagy 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ához azonban ezek a paraméterek kifejezetten jelezhetik a keresésbe belefoglalandó vagy kihagyott elemeket.
[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álása
Ez a parancsmag két paraméterkészletet használ (ScriptParameterSet és PatternParameterSet, ami az alapértelmezett), az adathozzáférésben használt két paraméterkészlet neveként.
PatternParameterSet az alapértelmezett paraméterkészlet, és a Pattern paraméter megadásakor használatos.
ScriptParameterSet akkor használatos, ha a felhasználó alternatív keresési mechanizmust ad meg a Script paraméteren keresztül. További információ a paraméterkészletekről: Paraméterkészletek hozzáadása parancsmaghoz.
Bemeneti feldolgozási módszerek felülírása
A parancsmagoknak felül kell bírálnia egy vagy több bemeneti feldolgozási módszert a System.Management.Automation.PSCmdlet osztályhoz. További információ a bemeneti feldolgozási módszerekről: Az első parancsmag létrehozása.
Ez a parancsmag felülbírálja a System.Management.Automation.Cmdlet.BeginProcessing metódust a lefordított reguláris kifejezések tömbjének indításkor történő létrehozásához. Ez növeli a teljesítményt olyan keresések során, amelyek nem használnak egyszerű egyeztetést.
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 a felhasználó által a parancssorban megadott sztringek feldolgozásához. A sztringkijelölés eredményeit egyéni objektum formájában írja le egy privát MatchString metódus meghí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 elérési útja által jelzett szolgáltatót, hogy hozzáférhessen az adatokhoz. A rendszer a System.Management.Automation.SessionState objektumot használja a szolgáltatóhoz való hozzáféréshez, míg a parancsmag System.Management.Automation.PSCmdlet.InvokeProvider* tulajdonsága a szolgáltató megnyitására szolgál. A tartalomhoz való hozzáférést a megnyitott szolgáltató System.Management.Automation.ProviderIntrinsics objektumának lekérésével lehet biztosítani.
Ez a minta Select-Str parancsmag a System.Management.Automation.ProviderIntrinsics.Content* tulajdonsággal teszi elérhetővé a vizsgálandó tartalmat. Ezután meghívhatja a System.Management.Automation.ContentCmdletProviderIntrinsics.GetReader* metódust, átadva a szükséges Windows PowerShell-útvonalat.
Kódminta
Az alábbi kód a Select-Str parancsmag ezen verziójának implementálását mutatja be. Vegye figyelembe, hogy ez a kód tartalmazza a parancsmagosztályt, a parancsmag által használt privát metódusokat és a parancsmag regisztrálásához használt Windows PowerShell beépülő modulkódot. A parancsmag regisztrálásával kapcsolatos további információkért lásd: Parancsmag létrehozása.
//
// 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 létrehozása
A parancsmag implementálása után regisztrálnia kell azt a Windows PowerShellben egy Windows PowerShell beépülő modulon keresztül. A parancsmagok regisztrálásáról további információt a parancsmagok, szolgáltatók és gazdagépalkalmazások .
A parancsmag tesztelése
Ha a parancsmag regisztrálva lett a Windows PowerShellben, a parancssorban futtatva tesztelheti. Az alábbi eljárással tesztelheti a minta Select-Str parancsmagot.
Indítsa el a Windows PowerShellt, és keressen rá a Jegyzetek fájlban a sorok előfordulására a ".NET" kifejezéssel. 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 több szóból áll.
Select-Str -Path "notes" -Pattern ".NET" -SimpleMatch=$falseMegjelenik a következő kimenet.
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 : .NETKeressen rá a Jegyzetek fájlban a sorok előfordulására a "over" szóval, majd bármely más szöveggel. A
SimpleMatchparaméter afalsealapértelmezett értékét használja. A keresés nem érzékeny a kis- és nagybetűkre, mert aCaseSensitiveparaméter értékefalse.Select-Str -Path notes -Pattern "over*" -SimpleMatch -CaseSensitive:$falseMegjelenik a következő kimenet.
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*Keresés a Jegyzetek fájlban egy reguláris kifejezéssel mintaként. A parancsmag betűrendes karaktereket és zárójelek közé zárt üres szóközöket keres.
Select-Str -Path notes -Pattern "\([A-Za-z:blank:]" -SimpleMatch:$falseMegjelenik a következő kimenet.
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:]A "Paraméter" szó előfordulásainál végezzen kis- és nagybetűkre vonatkozó keresést a Notes fájlban.
Select-Str -Path notes -Pattern Parameter -CaseSensitiveMegjelenik a következő kimenet.
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 : ParameterKeressen rá a Windows PowerShell-lel szállított változószolgáltatóban olyan változókra, amelyek numerikus értékei 0 és 9 között vannak.
Select-Str -Path * -Pattern "[0-9]"Megjelenik a következő kimenet.
IgnoreCase : True LineNumber : 1 Line : 64 Path : Variable:\MaximumHistoryCount Pattern : [0-9]Használjon szkriptblokkot a "Pos" sztring SelectStrCommandSample.cs kereséséhez. A
-cmatchoperátor kis- és nagybetűket nem érzékelyítő mintaegyezést hajt végre.Select-Str -Path "SelectStrCommandSample.cs" -Script { if ($args[0] -cmatch "Pos"){ return $true } return $false }Megjelenik a következő kimenet.
IgnoreCase : True LineNumber : 37 Line : Position = 0. Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\SelectStrCommandSample.cs Pattern :
Lásd még:
Windows PowerShell-parancsmag létrehozása
Az első parancsmag létrehozása
A rendszer módosító parancsmag létrehozása
A Windows PowerShell-szolgáltató tervezése
Parancsmagok, szolgáltatók és gazdagépalkalmazások regisztrálása)