Я работаю над ПО C для консольного приложения и пытаюсь получить значения командной строки из конфигурации после использования AddCommandLine в настройке.
csproj
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
Программный класс
public static class Program
{
public static async Task Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.RollingFile("Logs//log.txt")
.CreateLogger();
await CreateHostBuilder(args)
.Build()
.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFile("settings.json", true, true);
config.AddCommandLine(args);
})
.ConfigureServices((hostcontext, services) =>
{
services.AddHostedService<ConsoleApp>();
});
}
ConsoleApp class
public class ConsoleApp : IHostedService
{
private readonly IConfiguration config;
private readonly ILogger<ConsoleApp> log;
public ConsoleApp(IConfiguration configuration, ILogger<ConsoleApp> logger)
{
config = configuration;
log = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
var t = config.GetSection("Args");
Parser.Default.ParseArguments<DeleteOptions>(t)
.WithParsed<DeleteOptions>()
.WithNotParsed();
foreach (var c in config.AsEnumerable())
{
log.LogInformation($"{c.Key, -15}:{c.Value}");
}
log.LogInformation($"Completing Start Task");
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
log.LogInformation($"Complete End Task");
return Task.CompletedTask;
}
}
Раздел Parser перед foreach l oop не компилируется, а вывод l oop не выводит ни одного из добавленных мною аргументов.
Мне известен общий совет, что var someValue = Configuration.GetValue<int>("MySetting:SomeValue");
, где аргумент --MySetting=SomeValue
- это рекомендуемый способ получения значений строки cmd.
Значения, которые я использую в качестве параметров, delete -e CI -t depchpolestar -l de-DE
, и когда я смотрю на свой объект конфигурации, я вижу
, поэтому я думаю, что строка var t = config.GetSection("Args");
должна получить массив args. Я также попробовал var t = config.GetValue<string[]>("Args");
, но ни один из них не работает. Мне кажется, что индекс 4 объекта конфигурации - это строковый массив с ключом «Args»
Как мне получить массив строк, чтобы я мог передать его в метод ParseArguments CommandLineParser?
[ Править] Одно решение:
Теперь я могу передать аргументы, но это не очень хороший подход; Если я создаю аргумент как --delete "-e CI -t depchpolestar -l de-DE"
вместо delete -e CI -t depchpolestar -l de-DE
и добавлю следующий код в класс ConsoleApp:
var args = config.GetValue<string>("delete");
string[] arguments = null;
if(!string.IsNullOrEmpty(args))
{
var tempArgs = args.Split(" ");
arguments = new string[tempArgs.Length + 1];
arguments[0] = "delete";
for(int i = 0; i < tempArgs.Length; ++i)
{
arguments[i + 1] = tempArgs[i];
}
}
Parser.Default.ParseArguments<DeleteOptions>(arguments)
.WithParsed<DeleteOptions>(async c => await c.Dowork())
.WithNotParsed(HandleParseError);
выполнение попадет в метод DoWork. Хорошо, но DeleteOptions.cs определяет глагол, и намерение состоит в том, чтобы добавить больше команд. Так что больше работы, но идти в правильном направлении.
[Edit] Я также понял, что мне не нужно добавлять вызов AddCommandLine()
, поскольку они добавляются по умолчанию.