Showing posts with label Program Arguments. Show all posts
Showing posts with label Program Arguments. Show all posts

May 30, 2013

Command Line Parameter Accessors in .NET

How can strings containing white space be passed as command line parameters?
Here is the test console program:
class Program
{     
    static void Main(string[] args)
    {
        Console.WriteLine("Main(string[] args)=" + string.Join(",", args));
        Console.WriteLine("Environment.CommandLine=" + Environment.CommandLine);
        Console.WriteLine("Environment.GetCommandLineArgs()=" + string.Join(",", Environment.GetCommandLineArgs()));

        Console.WriteLine("");
        Console.WriteLine("Press any key to continue ...");
        Console.ReadKey(false);
    }
}
Using the following as command ine arguments:
Test -b:"Dummy User" "whataboutthis?" /x'Does this work' /a:another a"rgument
Produces this (the command line arguments are comma separated):
Main(string[] args)=Test,-b:Dummy User,whataboutthis?,/x'Does,this,work',/a:another,argument
Environment.CommandLine="C:\Users\...\bin\Debug\TestAccountName.vshost.exe" Test -b:"Dummy User" "whataboutthis?" /x 'Does this work' /a:another a"rgument
Environment.GetCommandLineArgs()=C:\Users\...\bin\Debug\TestAccountName.vshost.exe,Test,-b:Dummy User,whataboutthis? ,/x'Does,this,work',/a:another,argument

Looks like quotation characters "" can be used to enclose a part of a command line that contains white space, the quotation characters themselves are removed. Placing matching quotation characters around/within a command line argument ensures that it is interpreted as a single command line argument even if it contains whitespace characters. Quotation characters are stripped from the command line parameters as they are processed so they will not appear in the arguments.

Summary
Main(string[] args)
  • Gives access to ONLY the command line parameters themselves.
  • Executable is NOT included as a command line parameter.
  • Quotation marks can be used to capture a parameter or part of a parameter containing whitespace
Environment.CommandLine
  • Gives access to the raw command line
Environment.GetCommandLineArgs()
  • Gives access to ALL the command line parameters.
  • Executable is first command line parameter.
  • Quotation marks can be used to capture a parameter or part of a parameter containing whitespace

November 26, 2009

Accessing Command Line Arguments In WPF

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs sea)
    {
        CommandLine.Instance.SetArguments(sea.Args);
        base.OnStartup(sea);
    }
}

public class CommandLine
{
    private CommandLine()
    {}

    private static readonly CommandLine instance = new CommandLine();

    public static CommandLine Instance
    {
        get { return instance; }
    }

    public IEnumerable Arguments
    {
        get { return args; }
    }

    public void SetArguments(string[] args)
    {
        this.args = args ?? new string[0];
    }

    private string[] args = new string[0];
}
then to use
private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            foreach (string arg in CommandLine.Instance.Arguments)
            {
                if (arg.ToUpper() == "/C")
                {
                    if (System.Windows.Forms.Clipboard.ContainsText())
                    {
                        tbCode.Text = System.Windows.Forms.Clipboard.GetText();
                    }
                }
            }

        }
Doh!
Even easier:
string[] arguments = Environment.GetCommandLineArgs();
When processing command line args using Environment.CommandLineArgs(), found that the system automatically matches " in an argument. So if you have a path that contains a spaces, as long as that path is wrapped with " marks, the path will not be parsed into multiple arguments but rather appear as a single argument. eg.:
-myArg:C:\Program Files\MyProgram\Something.exe
will get parsed as multiple arguments:
  • -myArg:C:\Program
  • Files\MyProgram\Something.exe
whereas
-myArg:"C:\Program Files\MyProgram\Something.exe"
will get parsed as a single argument:
  • -myArg:C:\Program Files\MyProgram\Something.exe

Have also noticed that carriage return line feeds can get sucked into a command line argument. Perhaps a "Trim()" should be applied to each argument string before it is processed to be sure this whitespace is removed. Here is a sample command line parser:
internal class CommandLineParser
{
    public string Drive { get; set; }
    public string TrueCryptFile { get; set; }
    public string KeyFile { get; set; }

    const string DrivePrefix = "-D";
    const string TrueCryptFilePrefix = "-T";
    const string KeyFilePrefix = "-K";

    public void CommandLineArgs(string[] args)
    {
        //string[] args = Environment.GetCommandLineArgs();
        Debug.WriteLine("Args:" + string.Join(",", args));
        int ix = 0;
        foreach (string arg in args)
        {
            Debug.WriteLine("arg[" + ix++.ToString() + "]=\'" + arg + "\'");
        }
        foreach (string rawArg in args)
        {
            // Get rid of whitespace chars at the beginning and end
            string arg = rawArg.Trim(); 
            if (arg.Length < 2)
              continue;
            string argument = (arg[0] == '/') ? "-" + arg.Substring(1) : arg;
            int end = argument.IndexOf(':');
            if ((end == -1) && ((end + 1) >= argument.Length))
                continue;
            if (argument.ToUpper().StartsWith(DrivePrefix))
            {
                Drive = argument.Substring(end + 1).Substring(0, 1) + ":";
            }
            else if (argument.ToUpper().StartsWith(TrueCryptFilePrefix))
            {
                TrueCryptFile = argument.Substring(end + 1);
            }
            else if (argument.ToUpper().StartsWith(KeyFilePrefix))
            {
                KeyFile = argument.Substring(end + 1);
            }
        }
        Debug.WriteLine("Processed command line args:");
        Debug.WriteLine("Drive=\"" + Drive + "\"");
        Debug.WriteLine("TrueCryptFile=\"" + TrueCryptFile + "\"");
        Debug.WriteLine("KeyFile=\"" + KeyFile + "\"");
    }
}

// and tester (not really finished)
class CommandLineParserTester
{
    public void TestCommandLineParser()
    {
        CommandLineParser clp = new CommandLineParser();
        clp.CommandLineArgs(new string[] { 
            @"-D:M",
            @"-T:F:/Temp/truecrypt.tc",
            @"-K:F:/Temp/truecrypt.keyfile" });
        Assert(clp.Drive == "M:");
        Assert(clp.TrueCryptFile == @"F:/Temp/truecrypt.tc");
        Assert(clp.KeyFile == @"F:/Temp/truecrypt.keyfile");
    }
}