Reputation: 914
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
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