Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOException when ParserSettings loaded in WPF App #409

Closed
LordPinhead opened this issue Feb 7, 2019 · 17 comments
Closed

IOException when ParserSettings loaded in WPF App #409

LordPinhead opened this issue Feb 7, 2019 · 17 comments
Milestone

Comments

@LordPinhead
Copy link

When i use the Library in my WPF App (not Console App), there will be thrown an IOException in the Constructor of ParserSettings. It will be catched and DefaultMaximumHeight will be set.
But it would, in my opinion, cleaner with that code:


            try
            {
                if (Console.IsOutputRedirected || Console.WindowWidth < 1)
                {
                    maximumDisplayWidth = DefaultMaximumLength;
                }
                else
                {
                    maximumDisplayWidth = Console.WindowWidth;
                }
            }
            catch (IOException)
            {
                maximumDisplayWidth = DefaultMaximumLength;
            }

If you agree, i could do a pull request and merge it.

Best regards
Lord_Pinhead

@jairbubbles
Copy link

Same problem here.

Your solution seems good to me!

@moh-hassan
Copy link
Collaborator

@LordPinhead
Is the issue still exist in v2.5.0?

@JakubLinhart
Copy link

JakubLinhart commented May 21, 2019

Same issue in 2.5.0:

 	mscorlib.dll!System.IO.__Error.WinIOError(int errorCode, string maybeFullPath)	Unknown
 	mscorlib.dll!System.Console.GetBufferInfo(bool throwOnNoConsole, out bool succeeded)	Unknown
 	mscorlib.dll!System.Console.WindowWidth.get()	Unknown
 	CommandLine.dll!CommandLine.ParserSettings.ParserSettings()	Unknown
 	CommandLine.dll!CommandLine.Parser..cctor.AnonymousMethod__20_0()	Unknown
 	mscorlib.dll!System.Lazy<CommandLine.Parser>.CreateValue()	Unknown
 	mscorlib.dll!System.Lazy<CommandLine.Parser>.LazyInitValue()	Unknown

@moh-hassan
Copy link
Collaborator

Can you post a simple demo application to repro your issue.

@moh-hassan
Copy link
Collaborator

I couldn't repro your issue , and my wpf demo application is working fine.
Have a look to the attached project and modify it to reproduce the Exception, or send me you demo for investigation.

WpfApp1.zip

@JakubLinhart
Copy link

I'm not able to reproduce it in a minimal example project. It works fine for me also. The real project is far from "minimal": https://github.com/uoinfusion/Infusion/blob/e88086438a78eb7d388b5122e9ceb9cc535210fe/Infusion.Desktop/CommandLine/Handler.cs#L15

@LordPinhead
Copy link
Author

When i am back at work, i will make a sample projekt, should be online by the end of the week.

@LordPinhead
Copy link
Author

You Need to deactivate "Options -> Debugging -> Just my code" or the Exception will never be printed in Visual Studio. The Exception will still occure, but hidden.
I send the Project home to upload it, our Firewall dont like Github Uploads :-)

@moh-hassan
Copy link
Collaborator

moh-hassan commented May 27, 2019

I tried the next unit test for range of values 0-20 of MaximumDisplayWidth

    [Fact]
    public void Test1()
    {            
        var setting= new ParserSettings
        {
            MaximumDisplayWidth = 1, //cause error in range 1-20 , and may be different range based on the length of specification
            HelpWriter = Console.Out
        };
        var args=new string[] {"zz"};
        var parser= new Parser(setting);
        var result= parser.ParseArguments<Simple_Options>(args);
       
    }

An Exception is fired:

System.ArgumentOutOfRangeException
Length cannot be less than zero.
Parameter name: length
at System.String.Substring(Int32 startIndex, Int32 length)
at CommandLine.Text.HelpText.AddOption(String requiredWord, Int32 maxLength, Specification specification, Int32 widthOfHelpText) in F:\commandline-2.5\CommandlineFork_2.5\src\CommandLine\Text\HelpText.cs:line 846
...

The following line is the start of the cause of error

      // L#781 in HelpText.cs
     // private HelpText AddOptionsImpl(IEnumerable<Specification> specifications, string requiredWord, int maximumLength)		

     var remainingSpace = maximumLength - (maxLength + 6);

The remainingSpace is negative and cause string processing error

I think this module of wrapping lines need heavily debugging and correction to avoid the negative value
and DisplayWidth should have also minimum value to be adjusted

This revision and correction need co-operation with us to resolve this issue and submit PR.

@moh-hassan
Copy link
Collaborator

@LordPinhead
Waiting your Repro demo :)

@LordPinhead
Copy link
Author

Sorry, had a little stress the last week. Have a look https://github.com/LordPinhead/CommandLineWPFTestApp , just deactivate the "debug own code only" option.

@moh-hassan
Copy link
Collaborator

Thanks @LordPinhead for the Demo.
I could repro the IOException using your demo.
The root problem is the Redirection of Console, so this line raise the IOException:

              maximumDisplayWidth = Console.WindowWidth;

The limits in using your solution Is that Console.IsOutputRedirected isn't supported in net40 and the Compiler raise the error:

Error CS0117 'Console' does not contain a definition for 'IsOutputRedirected'

Also, Console.WindowWidth can cause other Exceptions like ArgumentOutOfRangeException

The try ..catch clause stop the propagation of IOException, catch it and handling it:

           try
           {
          ...
           catch (IOException)
          {
           maximumDisplayWidth = DefaultMaximumLength;
          }

What is you suggestion?

@LordPinhead
Copy link
Author

If Console.IsOutputRedirected is 4.5 and up, we could use preprocessor ifs.

´´´
#if NET40
// Do something, i could look it up like using System.Console.WindowHeight
#else
// Console.IsOutputRedirected Fix

´´´

So we could route depending on the framework used

@jairbubbles
Copy link

I think you can just remove the test on NET40.

Most WPF app nowadays will target NET45. The goal here is just to suppress an exception. I doubt we can achhieve it without that function.

@LordPinhead
Copy link
Author

Whats the status? Should it be cut off from Net40 or not? At some point, there will be no systems using the old framework and i think it's time to send Net40 into his retirement.

@dos-ise
Copy link

dos-ise commented Mar 5, 2020

I can still reproduce this with version 2.7.82
Are there any updates?
2020-03-05_11h27_54

@moh-hassan
Copy link
Collaborator

moh-hassan commented Mar 5, 2020

The exception is handled by try ..catch and is not fired at Release Configuration. It's caught and swallowed by setting Console.WindowWidth=80 when redirected in WPF.
In debugging, you can configure the debugger to ignore breaking on the First Chance Exception of IOException and it will ignore it (because it's handled and not re-thrown again) using Debug > Windows > Exception Settings.

This issue will be fixed in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants