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.
System.CommandLine egyértelmű elkülönítést biztosít a parancssori elemzés és a művelethívás között. Az elemzési folyamat felelős a parancssori bemenet elemzéséért, valamint egy ParseResult olyan objektum létrehozásáért, amely tartalmazza az elemzési értékeket (és az elemzési hibákat). A művelethívási folyamat felelős az elemzett parancshoz, beállításhoz vagy direktívához társított művelet meghívásáért (az argumentumok nem rendelkezhetnek műveletekkel).
Az oktatóanyag első lépéseiből System.CommandLine származó alábbi példában a ParseResult parancssori bemenet elemzésével jön létre. Nincsenek definiálva vagy meghívva műveletek:
using System.CommandLine;
using System.CommandLine.Parsing;
namespace scl;
class Program
{
static int Main(string[] args)
{
Option<FileInfo> fileOption = new("--file")
{
Description = "The file to read and display on the console."
};
RootCommand rootCommand = new("Sample app for System.CommandLine");
rootCommand.Options.Add(fileOption);
ParseResult parseResult = rootCommand.Parse(args);
if (parseResult.Errors.Count == 0 && parseResult.GetValue(fileOption) is FileInfo parsedFile)
{
ReadFile(parsedFile);
return 0;
}
foreach (ParseError parseError in parseResult.Errors)
{
Console.Error.WriteLine(parseError.Message);
}
return 1;
}
static void ReadFile(FileInfo file)
{
foreach (string line in File.ReadLines(file.FullName))
{
Console.WriteLine(line);
}
}
}
A rendszer meghív egy műveletet egy adott parancs (vagy irányelv vagy beállítás) sikeres elemzésekor. A művelet egy delegált, aki argumentumot ParseResult használ, és egy kilépési kódot ad int vissza (aszinkron műveletek is elérhetők). A metódus visszaadja a System.CommandLine.Parsing.ParseResult.Invoke kilépési kódot, és annak jelzésére használható, hogy a parancs végrehajtása sikeresen megtörtént-e.
Az oktatóanyag első lépéseinek System.CommandLine következő példájában a művelet a gyökérparancshoz van definiálva, és a parancssori bemenet elemzése után lesz meghívva:
using System.CommandLine;
namespace scl;
class Program
{
static int Main(string[] args)
{
Option<FileInfo> fileOption = new("--file")
{
Description = "The file to read and display on the console."
};
RootCommand rootCommand = new("Sample app for System.CommandLine");
rootCommand.Options.Add(fileOption);
rootCommand.SetAction(parseResult =>
{
FileInfo parsedFile = parseResult.GetValue(fileOption);
ReadFile(parsedFile);
return 0;
});
ParseResult parseResult = rootCommand.Parse(args);
return parseResult.Invoke();
}
static void ReadFile(FileInfo file)
{
foreach (string line in File.ReadLines(file.FullName))
{
Console.WriteLine(line);
}
}
}
Egyes beépített szimbólumok, például System.CommandLine.Help.HelpOptiona , System.CommandLine.VersionOptionés System.CommandLine.Completions.SuggestDirectiveaz előre definiált műveletek. Ezeket a szimbólumokat a rendszer automatikusan hozzáadja a gyökérparancshoz a létrehozáskor, és amikor meghívja a System.CommandLine.Parsing.ParseResultparancsot, azok "csak működnek". A műveletek használatával az alkalmazáslogikára összpontosíthat, míg a kódtár gondoskodik a beépített szimbólumok műveleteinek elemzéséről és meghívásáról. Ha szeretné, ragaszkodhat az elemzési folyamathoz, és nem definiálhat semmilyen műveletet (mint a fenti első példában).
ParseResult
Az ParseResult osztály a parancssori bemenet elemzésének eredményeit jelöli. Ezt kell használnia a beállítások és argumentumok elemzési értékeinek lekéréséhez (függetlenül attól, hogy műveleteket használ-e vagy sem). Azt is ellenőrizheti, hogy voltak-e elemzési hibák vagy nem egyező jogkivonatok.
ÉrtéketKér
A ParseResult.GetValue metódus lehetővé teszi a beállítások és argumentumok értékeinek lekérését:
int integer = parseResult.GetValue(delayOption);
string? message = parseResult.GetValue(messageOption);
Az értékeket név szerint is lekérheti, de ehhez meg kell adnia a lekérni kívánt érték típusát.
Az alábbi példa c#-gyűjtemény inicializálókkal hoz létre gyökérparancsot:
RootCommand rootCommand = new("Parameter binding example")
{
new Option<int>("--delay")
{
Description = "An option whose argument is parsed as an int."
},
new Option<string>("--message")
{
Description = "An option whose argument is parsed as a string."
}
};
Ezután a metódust használja az GetValue értékek név szerinti lekéréséhez:
rootCommand.SetAction(parseResult =>
{
int integer = parseResult.GetValue<int>("--delay");
string? message = parseResult.GetValue<string>("--message");
DisplayIntAndString(integer, message);
});
Ez a túlterhelés GetValue megszerzi a megadott szimbólumnévhez tartozó elemzett vagy alapértelmezett értéket, az elemzett parancs körülményei között (nem a teljes szimbólumfa esetén). A szimbólum nevét fogadja el, nem pedig egy aliast.
Elemzési hibák
A ParseResult.Errors tulajdonság az elemzési folyamat során előforduló elemzési hibák listáját tartalmazza. Minden hibát egy ParseError objektum jelöl, amely a hibával kapcsolatos információkat tartalmazza, például a hibaüzenetet és a hibát okozó jogkivonatot.
Amikor meghívja a metódust, az ParseResult.Invoke(InvocationConfiguration) egy kilépési kódot ad vissza, amely jelzi, hogy az elemzés sikeres volt-e. Ha elemzési hibák történtek, a kilépési kód nem nulla, és az összes elemzési hiba a standard hibára lesz nyomtatva.
Ha nem hívja meg a ParseResult.Invoke metódust, a hibákat önállóan kell kezelnie, például nyomtatással:
foreach (ParseError parseError in parseResult.Errors)
{
Console.Error.WriteLine(parseError.Message);
}
return 1;
Nem egyező egységek
A UnmatchedTokens tulajdonság tartalmazza az elemezett jogkivonatok listáját, de nem felelt meg a konfigurált parancsoknak, beállításoknak vagy argumentumoknak.
A nem egyező tokenek listája olyan utasításokban hasznos, amelyek wrapperként funkcionálnak. A burkolóparancs egy sor token-t fogad, és továbbítja őket egy másik parancsnak vagy alkalmazásnak. A sudo linuxos parancs egy példa. Egy felhasználó nevét veszi a megszemélyesítéshez, amelyet egy parancs futtatása követ. A következő parancs például felhasználóként apt updatefuttatja a admin parancsot:
sudo -u admin apt update
Egy ilyen burkolóparancs implementálásához állítsa a parancs tulajdonságát System.CommandLine.Command.TreatUnmatchedTokensAsErrors a következőre false: . Ezután a System.CommandLine.Parsing.ParseResult.UnmatchedTokens tulajdonság tartalmazni fogja az összes olyan argumentumot, amely nem tartozik explicit módon a parancshoz. Az előző példában a ParseResult.UnmatchedTokens tartalmazza a apt és update tokeneket.
Műveletek
A műveletek olyan meghatalmazottak, amelyeket egy parancs (vagy lehetőség vagy irányelv) sikeres elemzésekor hív meg a rendszer. Argumentumot ParseResult vesznek fel, és egy (vagy int) kilépési kódot adnak vissza Task<int> . A kilépési kód azt jelzi, hogy a műveletet sikeresen végrehajtották-e.
System.CommandLine absztrakt alaposztályt CommandLineAction és két származtatott osztályt biztosít: SynchronousCommandLineAction és AsynchronousCommandLineAction. Az előbbi a kilépési kódot visszaadó int szinkron műveletekhez, míg az utóbbi a kilépési kódot visszaadó Task<int> aszinkron műveletekhez használatos.
Nem kell származtatott típust létrehoznia egy művelet definiálásához. A metódussal SetAction műveletet állíthat be egy parancshoz. A szinkron művelet lehet egy olyan meghatalmazott, aki argumentumot ParseResult használ, és egy kilépési kódot ad int vissza. Az aszinkron művelet lehet egy delegált, aki argumentumokat vesz fel ParseResult és CancellationToken ad Task<int>vissza.
rootCommand.SetAction(parseResult =>
{
FileInfo parsedFile = parseResult.GetValue(fileOption);
ReadFile(parsedFile);
return 0;
});
Aszinkron műveletek
A szinkron és aszinkron műveleteket nem szabad ugyanabban az alkalmazásban keverni. Ha aszinkron műveleteket szeretne használni, az alkalmazásnak aszinkronnak kell lennie. Ez azt jelenti, hogy minden műveletnek aszinkronnak kell lennie, és azt a metódust kell használnia, amely elfogadja a System.CommandLine.Command.SetAction kilépési kódot visszaadó Task<int> meghatalmazottat. Ezenkívül a CancellationToken műveletmeghatalmazottnak átadott műveletet tovább kell adni az összes visszavonható metódusnak, például a fájl I/O-műveleteinek vagy a hálózati kéréseknek.
Azt is meg kell győződnie, hogy a ParseResult.InvokeAsync(InvocationConfiguration, CancellationToken) metódust használja ahelyett Invoke, hogy . Ez a módszer aszinkron, és egy Task<int> kilépési kódot ad vissza. Emellett elfogad egy opcionális CancellationToken paramétert is, amely a művelet megszakítására használható.
Az alábbi kód egy túlterhelést SetAction használ, amely nem csak CancellationToken, hanem a következőt ParseResult is lekéri:
static Task<int> Main(string[] args)
{
Option<string> urlOption = new("--url", "A URL.");
RootCommand rootCommand = new("Handle termination example") { urlOption };
rootCommand.SetAction((ParseResult parseResult, CancellationToken cancellationToken) =>
{
string? urlOptionValue = parseResult.GetValue(urlOption);
return DoRootCommand(urlOptionValue, cancellationToken);
});
return rootCommand.Parse(args).InvokeAsync();
}
public static async Task<int> DoRootCommand(
string? urlOptionValue, CancellationToken cancellationToken)
{
using HttpClient httpClient = new();
try
{
await httpClient.GetAsync(urlOptionValue, cancellationToken);
return 0;
}
catch (OperationCanceledException)
{
await Console.Error.WriteLineAsync("The operation was aborted");
return 1;
}
}
Folyamatvégzítés időtúllépése
ProcessTerminationTimeout lehetővé teszi a folyamatvégzítés (Ctrl+C, SIGINT, ) SIGTERMjelzését és kezelését a CancellationToken meghívás során az összes aszinkron műveletnek átadott műveleten keresztül. Alapértelmezés szerint engedélyezve van (2 másodperc), de beállíthatja úgy, hogy null letiltsa.
Ha engedélyezve van, ha a művelet nem fejeződik be a megadott időkorláton belül, a folyamat leáll. Ez akkor hasznos, ha a leállítást elegánsan kezeli, például úgy, hogy menti az állapotot a folyamat leállítása előtt.
Az előző bekezdés mintakódjának teszteléséhez futtassa a parancsot egy olyan URL-címmel, amely egy ideig tart a betöltésig, és a betöltés befejezése előtt nyomja le a CtrlC+. MacOS rendszeren nyomja le a Command+. Például:
testapp --url https://learn.microsoft.com/aspnet/core/fundamentals/minimal-apis
The operation was aborted
Kilépési kódok
A kilépési kód egy művelet által visszaadott egész szám, amely azt jelzi, hogy a művelet sikeres vagy sikertelen volt. Konvenció szerint a sikerességet jelző kilépési 0 kód, míg a nem nulla érték hibát jelez. Fontos, hogy értelmes kilépési kódokat definiáljon az alkalmazásban, hogy egyértelműen közölje a parancsvégrehajtás állapotát.
Minden SetAction metódus túlterheléssel rendelkezik, amely egy olyan delegáltat fogad el, aki egy kilépési kódot ad vissza int , ahol a kilépési kódot explicit módon kell megadni, és egy túlterhelést, amely visszaadja 0.
static int Main(string[] args)
{
Option<int> delayOption = new("--delay");
Option<string> messageOption = new("--message");
RootCommand rootCommand = new("Parameter binding example")
{
delayOption,
messageOption
};
rootCommand.SetAction(parseResult =>
{
Console.WriteLine($"--delay = {parseResult.GetValue(delayOption)}");
Console.WriteLine($"--message = {parseResult.GetValue(messageOption)}");
// Value returned from the action delegate is the exit code.
return 100;
});
return rootCommand.Parse(args).Invoke();
}