1

I develop an application with command line parameters and use it in cmd shell and powershell. There it is obvious that the arguments are received differently in main() of my application.

static void Main(string[] args)
{
  // In cmd shell:  args[0] == "-ipaddress=127.0.0.1"
  // In powershell: args[0] == "-ipaddress=127"
  //            and args[1] == ".0.0.1"
}

Example: myApp.exe -ipaddress=127.0.0.1

In my C# application the arguments are interpreted differently depending on the shell I start the app in.

  • In cmd shell: arg[0]=-ipaddress=127.0.0.1
  • In powershell: arg[0]=-ipaddress=127 and arg[1]=.0.0.1

What is best practice here?

  • Should I join all args[] and parse the arguments in my application?
  • Should I rely on the shell's parser?
BlackTuareg
  • 160
  • 1
  • 11

2 Answers2

0

I would abandon cmd shell support completely and just created proper PowerShell cmdlet. Writing a Windows PowerShell Cmdlet. But I don't know your exact requirements.

In general calling executable from cmd and PowerShell should work same way. For example line, "> ping -n 3 google.com" just works fine no matter where you put it.

Sergey Tunnik
  • 428
  • 3
  • 8
  • Do you have a source for the latter? Is it a general requirement that commands should be copy pasted regardless of their shell? – BlackTuareg Mar 16 '18 at 09:03
  • This is how it work https://i.imgur.com/3kM4DoW.png PS resolves commands in this order: Alias, Function, Cmdlet, Native Windows commands. More details: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_command_precedence?view=powershell-6#command-precedence – Sergey Tunnik Mar 16 '18 at 15:09
0

tl;dr:

When calling from PowerShell, enclose the entire argument in '...' (single quotes) to ensure that it is passed as-is:

myApp.exe '-ipaddress=127.0.0.1'

Alternatively, `-escape the initial -:

myApp.exe `-ipaddress=127.0.0.1

You've run into a parsing bug[1] where PowerShell breaks an unquoted argument that starts with - in two at the first .

The following simplified example demonstrates that:

# Helper function that echoes all arguments.
function Out-Argument { $i = 0; $Args | % { 'arg[{0}]: {1}' -f ($i++), $_ }}

# Pass an unquoted argument that starts with "-" and has an embedded "."
Out-Argument -foo=bar.baz

The above yields:

arg[0]: -foo=bar
arg[1]: .baz

[1] The presumptive bug is present as of Windows PowerShell v5.1 / and up to at least PowerShell (Core) v7.3.6 and has been reported in GitHub issue #6291.
A PSv2 variation of the bug affects . when enclosed in "..." in the interior of the argument - see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775