Open Mapaler opened 2 months ago
System.CommandLine 2.0.0-beta4.22272.1 itself does not use Windows Forms and thus does not display help in a MessageBox.
I suppose your application could define a class that implements IConsole and collects the output to a StringBuilder, set that as InvocationContext.Console, and display the result in a MessageBox. However, the columns of the two-column help layout would be misaligned if the MessageBox has a proportional font.
System.CommandLine is tailored to console applications and thus by default attempts to write all its output (help and error output) to the console. But you got a WinForms app, which doesn't have a console attached to it, hence there will be no output from System.CommandLine be visible.
I set up the following code, but nothing is prompted after running.
Because quite probably you provided invalid or incomplete CLI arguments, which would lead System.CommandLine to write an error message to the console (which your WinForms app doesn't have) and not invoke the (root) command handler.
I'd suggest you create a class implementing System.CommandLine.IConsole
and pass an instance of it to the Invoke
method. System.CommandLine would then use this IConsole implementation for all its output. The implementation of this class would be responsible for gathering the output generated by System.CommandLine. After the Invoke
method returns, your program might then - depending on whether and which output has been collected - create a dialog with a text field/text area displaying the output from System.CommandLine using a mono-spaced font.
Thanks for the answer.
About first question, the rootCommand.SetHandler
was not executed, I found the problem.
I'll start by following the tutorial to build such code in console mode.
using System;
using System.CommandLine;
var foldersArgument = new Argument<string>
(name: "folders",
description: "Folders that need to be moved.");
var destinationOption = new Option<DirectoryInfo>(
name: "--destination",
description: "The file to read and display on the console.");
destinationOption.AddAlias("-dst");
var autoOption = new Option<bool>(
name: "--auto",
description: "Auto start process.");
autoOption.AddAlias("-a");
var rootCommand = new RootCommand("Move/Rename SkyScan Dataset Folder acquire by Sample Changer to new Destination.");
rootCommand.AddOption(destinationOption);
rootCommand.AddOption(autoOption);
rootCommand.Add(foldersArgument);
rootCommand.SetHandler((foldersValue, destinationOptionValue, autoOptionValue) =>
{
Console.WriteLine($"folders = {foldersValue}");
Console.WriteLine($"--destination = {destinationOptionValue}");
Console.WriteLine($"--auto = {autoOptionValue}");
},
foldersArgument, destinationOption, autoOption);
rootCommand.Invoke(args);
Starts with one Agument, it can be displayed correctly.:
D:\Folder1 --auto -dst D:\target
Starts with more Argument, the program does not automatically ignore redundant Argument.:
D:\Folder1 D:\Folder2 D:\Folder3 --auto -dst D:\target
new Argument<string>
to new Argument<string[]>
using System;
using System.CommandLine;
var foldersArgument = new Argument<string[]> //Changed
(name: "folders",
description: "Folders that need to be moved.");
var destinationOption = new Option<DirectoryInfo>(
name: "--destination",
description: "The file to read and display on the console.");
destinationOption.AddAlias("-dst");
var autoOption = new Option<bool>(
name: "--auto",
description: "Auto start process.");
autoOption.AddAlias("-a");
var rootCommand = new RootCommand("Move/Rename SkyScan Dataset Folder acquire by Sample Changer to new Destination.");
rootCommand.AddOption(destinationOption);
rootCommand.AddOption(autoOption);
rootCommand.Add(foldersArgument);
rootCommand.SetHandler((foldersValue, destinationOptionValue, autoOptionValue) =>
{
Console.WriteLine($"folders = {string.Join(", ", foldersValue)}"); //Changed
Console.WriteLine($"--destination = {destinationOptionValue}");
Console.WriteLine($"--auto = {autoOptionValue}");
},
foldersArgument, destinationOption, autoOption);
rootCommand.Invoke(args);
Starts with the following parameters:
D:\Folder1 D:\Folder2 D:\Folder3 --auto -dst D:\target
In the previous code in WinForm, rootCommand.SetHandler
only be executed with only one Argument passed.
After modifying the Argument to an array, I can finally get the multiple arguments passed.
using System.CommandLine;
namespace Move_Sample_Folder
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
var foldersArgument = new Argument<DirectoryInfo[]>
(name: "folders",
description: "Folders that need to be moved.");
var destinationOption = new Option<DirectoryInfo?>(
name: "--destination",
description: "The destination of folder witch you want to move.");
destinationOption.AddAlias("-dst");
var autoOption = new Option<bool>(
name: "--auto",
description: "Auto start process.");
autoOption.AddAlias("-a");
var rootCommand = new RootCommand("Move/Rename SkyScan Dataset Folder acquire by Sample Changer to new destination.");
rootCommand.AddOption(destinationOption);
rootCommand.AddOption(autoOption);
rootCommand.Add(foldersArgument);
rootCommand.SetHandler((foldersValue, destinationOptionValue, autoOptionValue) =>
{
MessageBox.Show($"folders = {string.Join(", ",foldersValue.Select(e => e.FullName))}\n" +
$"--destination = {destinationOptionValue}\n" +
$"--auto = {autoOptionValue}");
},
foldersArgument, destinationOption, autoOption);
rootCommand.Invoke(args);
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new MainForm(args));
}
}
}
About second question, show help dialog. Based on your suggestions, I found this reference Using a Custom IConsole with System.CommandLine I still don't understand the principle, so I just used his sample code and I can get the output.
I don't need output to console, but I need to quickly import data via parameters. Is it possible to parse with
System.CommandLine
inside WinForm? I set up the following code, but nothing is prompted after running.Also, as for #1389, I understand it to be in this form. For example, Notepad2 and DataViewer are desktop programs, but support many startup parameters. While
-?
, an additional window will pop up to display the help content