1

I am writing a console application where we have to update the multiple connection string on the installed application. I have used the "CommandLineParser" library with "Verb" feature. My requirement is to use a single command line to pass different connection string value.

Example:
 Installer.exe conn1 -sservername -uusername -ppassword conn2 -sservername -uusername -ppassword

Whereas in "CommandLineParser" it cannot be done? Is there any other library which i could make use of?

I have tried the following packages,

  1. CommandLineArgumentsParser
  2. CommandLineParser
  3. CLAP
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Raajkumar
  • 857
  • 2
  • 13
  • 26
  • Perhaps just send multiple values to a single argument, separated by some well known delimeter (like a comma or semi-colon), and then parse the argument on the client side: `Installer.exe -sservername "serverOne;serverTwo" -uusername "userOne;userTwo" -ppassword "passOne;passTwo"` – Rufus L May 18 '18 at 17:30
  • Sorry, I forgot to mention this. All these arguments are optional. They can just change the conn2 password. – Raajkumar May 18 '18 at 18:43

3 Answers3

1

You can simulate this with NDesk.Options, although you will have to write some validation code yourself.

In NDesk.Options you can register a handler for the default option ("<>"). That handler will run for each of the connections in your example. Every time you encounter a value for the default option, you can create a connection settings object, and fill out the latest one when the normal options are supplied.

public class ConnectionListParser : OptionSet
{
    public class ConnectionSettings
    {
        public string Name { get; set; }
        public string Servername { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
    }

    public List<ConnectionSettings> Connections {get;} = new List<ConnectionSettings>();        

    public ConnectionListParser() {     
        Add("<>", x => {                        
            Connections.Add(new ConnectionSettings() {
                Name = x
            });                             
        });

        Add("s:", x => Connections.Last().Servername = x);
        Add("u:", x => Connections.Last().Username = x);
        Add("p:", x => Connections.Last().Password = x);
    }
}

Usage:

var opts = new ConnectionListParser();
var remain = opts.Parse("conn1 -sservername1 -uusername1 -ppassword1 conn2 -sservername2 -uusername2 -ppassword2".Split(' '));
// or opts.Parse(args) when you have actual command line arguments to parse
foreach(var c in opts.Connections) {        
    Console.WriteLine($"Connection '{c.Name}': Username={c.Username};Password={c.Password};Servername={c.Servername}");
}
gnud
  • 77,584
  • 5
  • 64
  • 78
  • This is what I wanted. Thanks @@gnud. Is it possible to pass in the appsettings value as well? – Raajkumar May 18 '18 at 19:14
  • @Raajkumar What do you mean by "appsettings value"? – gnud May 18 '18 at 19:17
  • Means, apart from passing connection string arguments, I would like to pass in config values so that I can update the app.config's appSettings section – Raajkumar May 18 '18 at 19:20
  • If you want to override the value, then sure. But actually changing the app.config based on a command line flag sounds like a horrible idea. Please don't do that. – gnud May 18 '18 at 19:24
  • OK. Got it. Our current environment has 300+ machine, where each set of machines should be configured to point to a specific URL. So what would be the recommended way? – Raajkumar May 18 '18 at 19:28
  • That's a very broad question :) What tool are you using to configure your machines now? – gnud May 18 '18 at 19:30
  • We have an InnoSetup based installation package which contains the application along with the console app to update the App.Config file. These 300 machines are KIOSK type. This installer would be run by altiris tool – Raajkumar May 18 '18 at 19:33
  • Oh, I understand a bit better now, after you updated your question. This application is being run to change the app.config of some other application on the 300 machines. That's different, then I understand why you wanted to change the app.config. – gnud May 18 '18 at 19:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/171351/discussion-between-gnud-and-raajkumar). – gnud May 18 '18 at 19:36
1

Can't you just parse the command line parameters with a simple algorithm as follow?

class ConnectionString
{
  public string Conn { get; set; }
  public string Server { get; set; }
  public string user { get; set; }
  public string pass { get; set; }
}

class MainClass
{
  static int Main(string[] args)
  {
    // Test if input arguments were supplied:
    if (args.Length == 0)
    {
      System.Console.WriteLine("No parameters specified.");
      return 1;
    }

    List<ConnectionString> connections = new List<ConnectionString>():
        ConnectionString connec = null;
    for (int i = 0; i < args.Length; i++)
    {
      if (args[i].StartsWith("-s"))
      {
        if (connec != null)
        {
          connec.Server = args[i].Substring(2);
        }
        continue;
      }
      if (args[i].StartsWith("-u"))
      {
        if (connec != null)
        {
          connec.user = args[i].Substring(2);
        }
        continue;
      }
      if (args[i].StartsWith("-p"))
      {
        if (connec != null)
        {
          connec.pass = args[i].Substring(2);
        }
        continue;
      }
      connec = new ConnectionString();
      connec.Conn = args[i];

      connections.Add(connec);
    }

    // Do What you need to do from here

    return 0;
  }
}
Pic Mickael
  • 1,244
  • 19
  • 36
  • This is what we are using currently. I was looking for a library which has more options. – Raajkumar May 18 '18 at 19:36
  • More options to do what exactly? My version supports the optional parameters you mentioned. if you need more than that, you need to be more specific in your requirement from the get-go so we can help you better :) – Pic Mickael May 18 '18 at 19:38
  • I mean passing multiple connection string and app settings value in the same command line. I was looking for better viable solution. – Raajkumar May 18 '18 at 19:43
  • As far as I can understand the sample of code I wrote should cover that. So I must be missing something else. – Pic Mickael May 18 '18 at 19:47
  • So my command line arguments would look like this, conn1 -sservername1 -uusername1 -ppassword conn2 -sservername -uusername -ppassword someurl someurl.com/api/someendpoint – Raajkumar May 18 '18 at 19:54
  • 1
    Ok, now that is more clear. those last 2 parameters would mess with pretty much any algorithm you could find. I think you should define a setting for those too. For example -rsomeurl -esomeurl.com/api/someendpoint Other than that I do not see how could can distinguish them from a connection string. – Pic Mickael May 18 '18 at 19:57
0

CommandLineUtils has this functionality, see fake-git example.

Another possibility is the official System.CommandLine, see wiki example

Markus R
  • 541
  • 1
  • 4
  • 6
  • I've tried fake-git example, and it fails on this string: ``add "some path to existing file" commit -m="message"``, on -m argument specifically. – Aberro Feb 11 '22 at 00:16