3

I've been doing some googling and did not find any solution. The most common case of a path-argument combo has quotes like

"C:\Program Files\example.exe" -argument --argument -argument "argument argument"

"C:\Program Files\example.exe" /argument /argument /argument "argument argument"

They simply go through the entire thing, look for the second quote, then treat everything after that as an argument.

.

The second solution I found (see here) works without quotes yet only works for paths without spaces. See below.

This works: C:\Windows\System32\Sample.exe -args -args -args "argument argument"

This does not work: C:\Program Files\Sample.exe -argument "arg arg" --arg-arg

This works in the same manner. They look for the first space then treat everything after it as an argument, which will not work with some/most programs (the program files folder name has a space).

.

Is there a solution to this? I've tried to use and tweak numerous snippets and even tried to make my own regex statement yet they all failed. Code snippets or even a library would come in handy.

Thanks in advance!

EDIT: The snippets I found as per request

Snippet 1:

char* lpCmdLine = ...;
char* lpArgs = lpCmdLine;
// skip leading spaces
while(isspace(*lpArgs))
    lpArgs++;
if(*lpArgs == '\"')
{
    // executable is quoted; skip to first space after matching quote
    lpArgs++;
    int quotes = 1;
    while(*lpArgs)
    {
        if(isspace(*lpArgs) && !quotes)
            break;
        if(*lpArgs == '\"')
            quotes = !quotes;
    }
}
else
{
    // executable is not quoted; skip to first space
    while(*lpArgs && !isspace(*lpArgs))
        lpArgs++;
}
// TODO: skip any spaces before the first arg

Source 2: almost everything in here

Source 3: Various shady blogs

Community
  • 1
  • 1
Aloha
  • 864
  • 18
  • 40
  • 3
    Your example containing a path with a space without quotes wouldn't work in Windows either, so I wouldn't worry about it unless you've proved it's a problem. – Charles Mager Apr 23 '15 at 15:50
  • Just a question: Can I start a process using only a single string (Process.Start)? I'm aware that I have to separate the file path and arguments into two strings/parts. (processStarterName.Arguments = "-args -args "argument") – Aloha Apr 23 '15 at 15:57

1 Answers1

2

You could try a CSV parser like the only onboard in .NET, the VisualBasic.TextFieldParser:

List<string[]> allLineFields = new List<string[]>();
var textStream = new System.IO.StringReader(text);
using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(textStream))
{
    parser.Delimiters = new string[] { " " };
    parser.HasFieldsEnclosedInQuotes = true; // <--- !!!
    string[] fields;
    while ((fields = parser.ReadFields()) != null)
    {
        allLineFields.Add(fields);
    }
}

With a single string the list contains one String[], the first is the path, the rest are args.

Update: this works with all but your last string because the path is C:\Program Files\Sample.exe. You have to wrap it in quotes, otherwise the space in Program Files splits them into two parts, but that is a known issue with windows paths and scripts.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Okay. Let me try that. – Aloha Apr 23 '15 at 15:03
  • Well, guess I do need those quotes. Thanks anyways :) – Aloha Apr 23 '15 at 15:22
  • @PandaLion98: do you really want to have a solution which works for all possible formats? Maybe you can also parse that string, but is it really needed? How do you want to find the path, what does it separate from the rest? You cannot use the period because it could also be `C:\Program Files\Sample.Dir\SampleFile.exe`. And if you look for the very last period you could find one in the arguments. – Tim Schmelter Apr 23 '15 at 15:26
  • I'm gonna use this for logging anyways. This shouldn't cause a problem. – Aloha Apr 23 '15 at 15:57
  • This worked. I just added a bunch of delimiters and a few ifs. – Aloha Apr 23 '15 at 22:52