Console.Error should not be referenced in a static object
Changing the Console.Error throws System.ObjectDisposedException
Console.Error can be changed using Console.SetError() method, so having this as a static reference prevents using the "newly" assigned TextWriter as it keeps the referenced to the original instance which has been disposed.
"Cannot write to a closed TextWriter."
at System.IO.StringWriter.Write(String value)
at System.IO.TextWriter.SyncTextWriter.Write(String value)
at CommandLine.Parser.<>c__DisplayClass17_01.<DisplayHelp>b__1(IEnumerable1 _, TextWriter writer)
at CSharpx.MaybeExtensions.Do[T1,T2](Maybe1 maybe, Action2 action)
at CommandLine.Parser.<>c__DisplayClass17_01.<DisplayHelp>b__0(IEnumerable1 errors)
at CommandLine.ParserResultExtensions.WithNotParsed[T](ParserResult1 result, Action1 action)
at CommandLine.Parser.DisplayHelp[T](ParserResult1 parserResult, TextWriter helpWriter, Int32 maxDisplayWidth) at CommandLine.Parser.MakeParserResult[T](ParserResult1 parserResult, ParserSettings settings)
at CommandLine.Parser.ParseArguments(IEnumerable1 args, Type[] types) at TestApp.Program.Main(String[] args) in Program.cs:line 25 at TestApp.Tests.ProgramTest.Main_ShouldExecuteCommandSuccesfully(List1 args) in ProgramTest.cs:line 18
https://github.com/commandlineparser/commandline/blob/d443a51aeb3a418425e970542b3b96e9da5f62e2/src/CommandLine/Parser.cs#L22
private static readonly Lazy<Parser> DefaultParser = new Lazy<Parser>(() => new Parser(new ParserSettings { HelpWriter = Console.Error }));
I encountered a similar issue while testing a console main function which uses this commandlineparser. The act part of multiple tests defines args and executes this:
public async Task<ExecutionResult> executeMain(string[] args)
{
ExecutionResult result = new();
using StringWriter stdOutWriter = new();
using StringWriter stdErrWriter = new();
TextWriter stdOut = Console.Out;
TextWriter stdErr = Console.Error;
Console.SetOut(stdOutWriter);
Console.SetError(stdErrWriter);
result.exitCode = await Konfigurator.Main(args);
Console.SetError(stdErr);
Console.SetOut(stdOut);
result.stdOut = stdOutWriter.ToString();
result.stdErr = stdErrWriter.ToString();
Console.WriteLine("fin");
return result;
}
This works as expected as long as none of the commandline args are declared as 'required'. In that case the second test which runs fails with that 'Cannot write to a closed TextWriter' exeption. It seems to me that the out / error streams are manipulated but not properly restored after displaying the help message on an validation error.