Command line fun in .NET
-
void Main(string[] args)
is broken. The issue is this: It dequotes values but doesn't tell you which ones were quoted. So if you naively use these as arguments, you will interpret the literal string "/ifstale" as a command line switch/ifstale
instead of a literal string. Yes, the problem is a bit contrived, but it's kind of scary to think about the possibilities where something like it can crop up. It flies in the face of application robustness. My solution involves Environment.CommandLine which reports the raw command line argument, quotes and all. The issue with that is sometimes your .NET assembly is hosted by another executable, like dotnet.exe and then your arguments are all off by two. Here's what i have to do. Basically what I'm doing is making the switch -- normally, but / for windows, primarily because of file path issues causing ambiguities with / After that I crack the command line arguments, getting the exe name separately. I didn't post that code but it's here if you're interested: Environment.CommandLine cracker - Pastebin.com[^]var prefix = "--";
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
prefix = "/";
}
var cl = Environment.CommandLine;
string exename;
var clargs = CrackCommandLine(cl, out exename);
if (clargs.Count >= args.Length)
{
clargs = clargs.GetRange(clargs.Count - args.Length, args.Length);
}
else
{
clargs.Clear();
for (int i = 0; i < args.Length; i++)
{
clargs.Add(new KeyValuePair(false, args[i]));
}
}Then - get this - I have to count the arguments backward from the end to match them up to your actual executable's arguments, and that's the only thing the args[] array is good for. Now at the end of that code, you have keyvaluepair arguments where the Key is whether it's quoted or not, and the Value is the de-quoted, de-escaped value in any case. It's dirty, but it works.
Check out my IoT graphics library here: https://honeythecodewitch.com/gfx And my IoT UI/User Experience library here: https://honeythecodewitch.com/uix
-
void Main(string[] args)
is broken. The issue is this: It dequotes values but doesn't tell you which ones were quoted. So if you naively use these as arguments, you will interpret the literal string "/ifstale" as a command line switch/ifstale
instead of a literal string. Yes, the problem is a bit contrived, but it's kind of scary to think about the possibilities where something like it can crop up. It flies in the face of application robustness. My solution involves Environment.CommandLine which reports the raw command line argument, quotes and all. The issue with that is sometimes your .NET assembly is hosted by another executable, like dotnet.exe and then your arguments are all off by two. Here's what i have to do. Basically what I'm doing is making the switch -- normally, but / for windows, primarily because of file path issues causing ambiguities with / After that I crack the command line arguments, getting the exe name separately. I didn't post that code but it's here if you're interested: Environment.CommandLine cracker - Pastebin.com[^]var prefix = "--";
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
prefix = "/";
}
var cl = Environment.CommandLine;
string exename;
var clargs = CrackCommandLine(cl, out exename);
if (clargs.Count >= args.Length)
{
clargs = clargs.GetRange(clargs.Count - args.Length, args.Length);
}
else
{
clargs.Clear();
for (int i = 0; i < args.Length; i++)
{
clargs.Add(new KeyValuePair(false, args[i]));
}
}Then - get this - I have to count the arguments backward from the end to match them up to your actual executable's arguments, and that's the only thing the args[] array is good for. Now at the end of that code, you have keyvaluepair arguments where the Key is whether it's quoted or not, and the Value is the de-quoted, de-escaped value in any case. It's dirty, but it works.
Check out my IoT graphics library here: https://honeythecodewitch.com/gfx And my IoT UI/User Experience library here: https://honeythecodewitch.com/uix
I agree, I don't do that. I parse
Environment.CommandLine
myself (using a rather complex Regular Expression). Oh, thats right, I have an article on it... ParsedCommandLine[^] (It's not up-to-date, I added more features to it over the years.) -
I agree, I don't do that. I parse
Environment.CommandLine
myself (using a rather complex Regular Expression). Oh, thats right, I have an article on it... ParsedCommandLine[^] (It's not up-to-date, I added more features to it over the years.)A regex is kind of complicated for that. I prefer using my looping dual state state machine (state is just represented by the
isQuote
bool. The technique i presented above is used in the latest GitHub bits of the project here: Program.Base: Drop In Command Line Application Functionality for Your Projects[^] It does: Command line parsing, using screen generation, error handling, file and argument object lifetime management, word wrapping (necessary for using screen anyway so i exposed it) stale file checking and progress reporting. It's a drop in file with no dependencies, and is targeted to .NET Framework as well as the newer stuff. (I have two files for it but the only difference between them is the .NET Framework (DNF) file does not have#nullable disable
at the top, which shuts up nullable reference type warnings in the newer C#. You just pick the one you need. If you can get it approved by your work you're more than welcome to it. I developed it because I got sick of writing essentially the same code over and over again. This is less work than that System.CommandLine stuff, and does more.Check out my IoT graphics library here: https://honeythecodewitch.com/gfx And my IoT UI/User Experience library here: https://honeythecodewitch.com/uix