Skip to content

.NET 8: CommandLineApplication.Execute with unknown command throws System.InvalidOperationException: Enumeration already finished #541

@craigktreasure

Description

@craigktreasure

Describe the bug

Using McMaster.Extensions.CommandLineUtils 4.1.0.

Upgrading my application from .NET 7 to .NET 8 and my tests and application started failing with an unexpected error when parsing unexpected commands.

Unhandled exception. System.InvalidOperationException: Enumeration already finished.
   at System.SZGenericArrayEnumerator`1.get_Current()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.CommandArgumentEnumerator.get_Current()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.CommandArgumentEnumerator.MoveNext()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.ProcessCommandOrParameter(CommandOrParameterArgument arg)
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.ProcessNext()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.Process()
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Parse(String[] args)
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
   at Program.<Main>$(String[] args) in C:\Users\craig\Desktop\MyApp\MyApp\Program.cs:line 10

To Reproduce

Create a simple sample app with the following:

MyApp.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFrameworks>net8.0;net7.0</TargetFrameworks>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.1.0" />
  </ItemGroup>

</Project>

Program.cs

using McMaster.Extensions.CommandLineUtils;

CommandLineApplication app = new();
app.HelpOption();
app.OnExecute(() =>
{
    app.ShowHelp();
    return 1;
});
return app.Execute(args);

Now run the app with an invalid command for each of the target frameworks:

~\Desktop\MyApp\MyApp
> dotnet run -f net7.0 -- invalid
Specify --help for a list of available options and commands.
Unhandled exception. McMaster.Extensions.CommandLineUtils.UnrecognizedCommandParsingException: Unrecognized command or argument 'invalid'
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.ProcessUnexpectedArg(String argTypeName, String argValue)
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.ProcessCommandOrParameter(CommandOrParameterArgument arg)
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.ProcessNext()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.Process()
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Parse(String[] args)
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
   at Program.<Main>$(String[] args) in C:\Users\craig\Desktop\MyApp\MyApp\Program.cs:line 10
~\Desktop\MyApp\MyApp
> dotnet run -f net8.0 -- invalid
Unhandled exception. System.InvalidOperationException: Enumeration already finished.
   at System.SZGenericArrayEnumerator`1.get_Current()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.CommandArgumentEnumerator.get_Current()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.CommandArgumentEnumerator.MoveNext()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.ProcessCommandOrParameter(CommandOrParameterArgument arg)
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.ProcessNext()
   at McMaster.Extensions.CommandLineUtils.CommandLineProcessor.Process()
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Parse(String[] args)
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
   at Program.<Main>$(String[] args) in C:\Users\craig\Desktop\MyApp\MyApp\Program.cs:line 10

Expected behavior

The result from the net7.0 invocation is what I would expect. It correctly indicates that the parameter wasn't recognized.

Additional context

I'm also seeing the issue with valid commands, but I haven't nailed down a minimal repro for that. I have a feeling the fix for the unexpected commands will either fix the same issue or shine light on a deeper issue.

Runtime information:

> dotnet --list-sdks
6.0.417 [C:\Program Files\dotnet\sdk]
7.0.404 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]

> dotnet --list-runtimes
Microsoft.AspNetCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions