Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Command Line Arguments, a smart way?

The way I always do it is to specify the arguments as a "name"/"value" pair e.g.

myprogram.exe -arg1 value1 -arg2 value2

This means that when you parse the command line you can put the argument/value pairs in a Dictionary with the argument as the key. Then your arg("SetTime") will become:

MessageBox.Show(dictionary["SetTime"]);

(Obviously you don't want the actual dictionary to be public.)

To get the arguments in the first place you can use:

string[] args = Environment.GetCommandLineArgs();

This will return all the arguments so you will need to parse the array in steps of two (after first checking that the length is a multiple of two + 1):

The first element of the array is the name of the executing program - MSDN Page - so your loop needs to start from one:

for (int index = 1; index < args.Length; index += 2)
{
     dictionary.Add(args[index], args[index+1]);
}

This loops in steps of two as you define each argument is a pair of values: the identifier and the actual value itself, e.g.

my.exe -arg1 value1 -arg2 value2

Then you can simply see if the argument is specified by seeing if the key -arg1 is in the dictionary and then read it's value:

string value;
if (dictionary.TryGetValue(arg, out value))
{
    // Do what ever with the value
}

This means you can have the arguments in any order and omit any arguments you don't want to specify.

The only drawback with this method is if you have a flag like -debug (for example) which could be logically implemented with the presence or absence of the flag will need to be specified as -debug true (or 1 or on), but it does simplify things if you have flags that do require values (like configuration file paths, database connection strings etc.)


There's another way to do this in WPF. Here's an article about it, and here's the steps to take:

First, you open App.xaml and you add Startup="Application_Startup" after the StartupUri="Window1.xaml", so your App.xaml will look like this:

<Application x:Class="ParametersForWPF.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml"
    Startup="Application_Startup">
    <Application.Resources>
    </Application.Resources>
</Application>

Then function Application_Startup will automatically be added to your App.xaml.cs file:

public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {

    }
}

Now inside this function you can check the args sent to the application. An example to do this is:

private void Application_Startup(object sender, StartupEventArgs e)
{
    foreach(string s in e.Args)
    {
        MessageBox.Show(s);
    }
}

If you need them as a Dictionary then you could easily implement ChrisF's answer inside the Application_Startup function.


this is how i handle both types of of arguments for example

myapp.exe -my-flag -another-flag -value-flag "Hello World"

Dictionary<string, string> arguments = new Dictionary<string, string>()

//e from StartupEventArgs e

for (int index = 0; index < e.Args.Length; index += 2)
{
    if(e.Args.Length == index+1 || e.Args[index + 1].StartsWith("-"))
    {
        arguments.Add(e.Args[index], string.Empty);
        index--;
    }
                    

    if (e.Args.Length >= index + 1 && !e.Args[index + 1].StartsWith("-"))
        arguments.Add(e.Args[index], e.Args[index + 1]);
}

You can could then check your values like so.

if(arguments.ContainsKey("my-flag")){
   arguments.TryGetValue("value-flag", valueFlag)
}