Aloha
Aloha

Reputation: 914

C# - Split executable path and arguments into two strings

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

Upvotes: 3

Views: 2341

Answers (1)

Tim Schmelter
Tim Schmelter

Reputation: 460118

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.

Upvotes: 2

Related Questions