command-line-api icon indicating copy to clipboard operation
command-line-api copied to clipboard

Pass JSON as argument

Open lucasmaj opened this issue 2 years ago • 7 comments

Spent hours trying to figure out how to pass valid JSON as argument value from command line. Double quote get stripped out:

myapp --param1 {"KEY":{}}

results in param1 having value {KEY:{}}

lucasmaj avatar Oct 04 '23 16:10 lucasmaj

Which operating system and shell is this?

KalleOlaviNiemitalo avatar Oct 04 '23 16:10 KalleOlaviNiemitalo

This is quite likely an effect of the startup code that transforms the given command line into an args string array that's being passed to the main method of your .NET program. Basically, said startup code expects the double-quotes escaped with a backslash character for them to be treated as ordinary characters.

Using the cmd.exe shell, doing this would be quite simple: cmd.exe>myapp --param1 {\"KEY\":{}}

With Powershell, it gets a little bit more complicated. Note the single quotes; without them Powershell itself would strip the double-quotes from the command line: PS>.\myapp --param1 '{\"KEY\":{}}'

If you are using another shell, you need to verify whether that shell treats backspaces and/or double-quotes in a special way. If so, you will have to apply that shell's syntax rules in a manner so that both the backspaces as well as the double-quotes are being passed to the called program.

elgonzo avatar Oct 04 '23 18:10 elgonzo

@lucasmaj doesn't appear to have been using PowerShell; it would have parsed {"KEY":{}} as a script block and Base64 encoded the content. (https://github.com/PowerShell/PowerShell/issues/4973, https://github.com/PowerShell/PowerShell/issues/10842)

KalleOlaviNiemitalo avatar Oct 04 '23 19:10 KalleOlaviNiemitalo

I happen to be using Windows Command Prompt. In this instance I am not launching app with command line args passed in. Instead I have infinite loop to Console.ReadLine() and pass to myRootCommand.Invoke() so every time user enters/pastes the args.

And thank you for prompt responses.

lucasmaj avatar Oct 04 '23 19:10 lucasmaj

Which version of the library are you using?

(UPDATE: It seems at least with the current master branch of the library code you would be out of luck regarding double quotes. When passing a single string of a commandline to the Parse method, the library uses its own SplitCommandLine method. Unfortunately, its current implementation does not seem to allow for escaping of double quotes and simply strips them away :-( )

elgonzo avatar Oct 04 '23 20:10 elgonzo

2.0.0-beta4.22272.1 which looks like is latest

lucasmaj avatar Oct 04 '23 21:10 lucasmaj

There are packages of newer versions of System.CommandLine on the daily builds nuget feed (see the project's readme.md). The latest as of writing this is 2.0.0-beta4.23407.1. But updating to this version wouldn't likely help you (not to mention the work it would require to adapt your existing code to the new API surface of the newer library versions.

Even with the current master branch of the library, when passing a single string of a commandline to the Parse method, the library uses its own SplitCommandLine method. Unfortunately, its current implementation does not seem to allow for escaping of double quotes and simply strips them away -- just as the CommandLineStringSplitter.Split method did in 2.0.0-beta4.22272.1 :-(

Not sure what the future holds regarding System.CommandLine's own SplitCommandLine method, as i am not involved with the project. But you might want to keep this discussion https://github.com/dotnet/command-line-api/issues/1758 on your radar, even though it doesn't really help you solve your problem now. (Basically, if you need to handle and retain double-quotes, currently you would have to do the splitting of the user input string by yourself and then passing the resulting string array to the Parse or Invoke method.)

elgonzo avatar Oct 04 '23 21:10 elgonzo