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.)


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)
}

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.