system.commandline

How do I get the second parameter in the system.commandline?
When I doubleclick on a associated (associated with my app) file the commandline is something like:
“c:\program files\myapp\myapp.exe” “c:\users\sander\database.db”

The quotes are in the string, so I thought I look for the literal pattern " " (double quote space double quote) to check wether there is a second parameter but how to search for quotes in Xojo?

Hi. Take a look at the SPLIT Command. Comes in handy for this.

Right! I looked into the split, but I took the space character as split parm, That went wrong. Thanks!

mmm… How would I search for the literal string " "?

dim ParmArray() as String ParmArray() = Split(system.commandline, "" "")
doesnt work. According to manual you have to use an extra quote…

You need 3 “'s x 2 Split(system.commandline, “”” “”") the first & last " are the string enclosures the inner pairs are the actual quotes.

dim ParmArray() as String ParmArray() = Split(system.commandline, """ """)

Thanks all

[quote=117006:@Alexander van der Linden]How do I get the second parameter in the system.commandline?
When I doubleclick on a associated (associated with my app) file the commandline is something like:
“c:\program files\myapp\myapp.exe” “c:\users\sander\database.db”

The quotes are in the string, so I thought I look for the literal pattern " " (double quote space double quote) to check wether there is a second parameter but how to search for quotes in Xojo?[/quote]

If Kem was around, he may have some magical Regex that does that in a pass, but here is my method which, as usual, has been tested.

A simple split will not do, because a typical argument call in Windows command line can be done with arguments without quotes, or with quotes for arguments containing spaces. Like so :

 "C:\\Users\\Michel\\AppData\\Local\\Temp\\DebugMy Application\\DebugMy Application.exe" "firstarg" "secondarg" thirdarg "fourth arg"

Notice how thirdarg has no quotes, and “fourth arg” contains a space.

So the trick is to be able to distinguish between spaces between arguments, and spaces inside arguments. What I do is firt replace quote-space and space-quote by §, then single quotes by §, then finally do the split with §. I have used § because it is unusual, but any other character can do.

dim buf as string = replaceall(system.CommandLine,chr(34)+" ","§") buf = replaceall(buf," "+chr(34),"§") buf = replaceall(buf,chr(34),"§") buf = replaceall(buf,"§§","§") dim myarray(-1) as string myarray = split(buf,"§") for i as integer = 0 to myarray.Ubound-1 ListBox1.addrow(myarray(i)) next

At the end, each argument is entered in a different row of the ListBox. It’s up to you to adapt the method to your own needs :slight_smile:

Hello Michel,

my first Split with space as argument went wrong because of the “Program Files” space. With the Split on the " " pair I’m not quite happy either because the split string still contains a " at the end. You have to trim that as well.

I’ll look into your suggestion. Thanks.

I believe to handle all situations, you’ll have to parse character by character because you can have a " in the actual parameter, for example:

sayhello.exe "John ^" Michaels ^" McDoe"

Should result in:

args(0) = sayhello.exe
args(1) = John " Michaels " McDoe

What would be nice is if we could have args() As String in GUI applications as we do in Command Line and Web.

[quote=117029:@Jeremy Cowgar]I believe to handle all situations, you’ll have to parse character by character because you can have a " in the actual parameter, for example:

sayhello.exe "John ^" Michaels ^" McDoe"

Should result in:

args(0) = sayhello.exe
args(1) = John " Michaels " McDoe

What would be nice is if we could have args() As String in GUI applications as we do in Command Line and Web.[/quote]

No need for character per character ;

System.CommandLine = ReplaceAll(System.CommandLine,"^"+chr(34),"›")
then after the split

arg(i) = ReplaceAll(arg(i),"›","^"+chr(34))

Hm, ran some tests and don’t think my previous assumption was correct. Playing now.

Actually, System.CommandLine does not interpret anything, so you get exactly what was entered.

This will work (just tried)

dim buf as string = ReplaceAll(System.CommandLine,"^"+chr(34),"›") buf = replaceall(buf,chr(34)+" ","§") buf = replaceall(buf," "+chr(34),"§") buf = replaceall(buf,chr(34),"§") buf = replaceall(buf,"§§","§") dim myarray(-1) as string myarray = split(buf,"§") for i as integer = 0 to myarray.Ubound-1 myarray(i) = ReplaceAll(myarray(i),"›",chr(34)) ListBox1.addrow(myarray(i)) next

Yes, you are right. I am bowing out of this discussion as I’m just confusing the issue. I am recollecting things when I was making an option parser for cross platform. Sorry to confuse things guys…

BTW, try

C:\\> hello.exe what are you "doing today" john?

I get 2 entries in the list box w/your code.

1: hello.exe what are you
2: doing today

[quote=117038:@Jeremy Cowgar] dim buf as string = ReplaceAll(System.CommandLine,"^"+chr(34),“›”)
buf = replaceall(buf,chr(34)+" “,”§")
buf = replaceall(buf," “+chr(34),”§")
buf = replaceall(buf,chr(34),"§")
buf = replaceall(buf,"§§","§")
dim myarray(-1) as string
myarray = split(buf,"§")
for i as integer = 0 to myarray.Ubound-1
myarray(i) = ReplaceAll(myarray(i),“›”,chr(34))
ListBox1.addrow(myarray(i))
next[/quote]

On the contrary, Jeremy, your input is quite valuable. You are not confusing the issue. The only way to test a method is to throw everything at it, and it should work reliably through. Obviously, I had not planned correctly, as indeed, this example does not parse correctly. I shall get back to the keyboard.

At first glance, there was indeed a flaw in my method : there was no plain blank separator. So I was parsing in a succession or space-quote and quote-space. If I replace all spaces, I mess the arg with a space in it. I will have to use Instr()…

No Instr(), but Regex. Here is a solution inspired by Kem Tekinay’s code he posted here : https://forum.xojo.com/14398-regex-getting-identical-matches-just-once

I changed the pattern and cleaned the quotes. Now it does report all the regular arguments, with or without quotes. The only case I did not address is the ^" token which escapes quotes. It would require an extra step, and I did not think it was used very often.

[code]dim sourceText as string = system.commandline
dim rx as new RegEx
rx.SearchPattern = “(”"[^""]+""|[^\s""]+)"
dim matches() as string
dim match as RegExMatch = rx.Search( sourceText )
while match <> nil
matches.Append ReplaceAll(match.SubExpressionString( 1 ),chr(34),"")
match = rx.Search()
wend

for i as integer = 0 to matches.ubound
ListBox1.AddRow matches(i)
next[/code]