Передача аргументов командной строки в С#
Я пытаюсь передать аргументы командной строки в приложение С#, но у меня есть проблема с передачей чего-то вроде этого
"C:\Documents and Settings\All Users\Start Menu\Programs\App name"
даже если я добавлю " "
в аргумент.
Вот мой код:
public ObjectModel(String[] args)
{
if (args.Length == 0) return; //no command line arg.
//System.Windows.Forms.MessageBox.Show(args.Length.ToString());
//System.Windows.Forms.MessageBox.Show(args[0]);
//System.Windows.Forms.MessageBox.Show(args[1]);
//System.Windows.Forms.MessageBox.Show(args[2]);
//System.Windows.Forms.MessageBox.Show(args[3]);
if (args.Length == 3)
{
try
{
RemoveInstalledFolder(args[0]);
RemoveUserAccount(args[1]);
RemoveShortCutFolder(args[2]);
RemoveRegistryEntry();
}
catch (Exception e)
{
}
}
}
И вот что я прохожу:
C:\WINDOWS\Uninstaller.exe "C:\Program Files\Application name\" "username" "C:\Documents and Settings\All Users\Start Menu\Programs\application name"
Проблема в том, что я могу правильно получить первый и второй аргументы, но последний из них получается как C:\Documents
.
Любая помощь?
Ответы
Ответ 1
Я только что проверил чек и проверил проблему. Это меня удивило, но это последний в первом аргументе.
"C:\Program Files\Application name\" <== remove the last '\'
Это требует большего объяснения, есть ли у кого-нибудь идеи? Я склонен называть это ошибкой.
Часть 2, я провел еще несколько тестов и
"X:\\aa aa\\" "X:\\aa aa\" next
становится
X:\\aa aa\
X:\\aa aa" next
Небольшое действие Google дает некоторое представление о блоге Jon Galloway, основными правилами являются:
- обратная косая черта - это символ escape
- всегда кавычки
- избегают обратных косых черт, когда они предшествуют цитате.
Ответ 2
Чтобы добавить ответ Яна Кемпа
Если сборка называется "myProg.exe", и вы передаете строку "C:\Documents and Settings\All Users\Start Menu\Programs\App name", поэтому
C:\>myprog.exe "C:\Documents and Settings\All Users\Start Menu\Programs\App name"
строка "C:\Documents and Settings\All Users\Start Menu\Programs\App name"
будет в args [0].
Ответ 3
Чтобы добавить к тому, что уже сказали все остальные, это может быть проблема с экранированием. Вы должны избегать обратной косой черты другой косой чертой.
Должно быть что-то вроде:
C: \ > myprog.exe "C:\\Documents and Settings\\Все пользователи\\Меню Пуска\\Programs\\Имя приложения
Ответ 4
В последнее время я заметил ту же самую неприятную проблему и решил написать синтаксический анализатор для анализа массива аргументов командной строки.
Примечание: проблема в том, что аргументы .NET CommandLine переданы в функцию static void Main (string [] args) escapes\"и \\. Это по дизайну, так как вы действительно можете передать аргумент, который имеет цитата или обратная косая черта в ней. Один пример:
скажите, что вы хотели передать следующее как один аргумент:
-msg: Эй, "Где ты?"
например.
sampleapp -msg: "Эй, \" Где вы при? \""
Как отправить его с поведением по умолчанию.
Если вы не видите причин, по которым кто-либо должен избегать цитат или обратных косых черт для вашей программы, вы можете использовать свой собственный синтаксический анализатор для синтаксического анализа командной строки, как показано ниже.
IE.
[program].exe "C:\test \" arg1 arg2
будет иметь args [0] = c:\test "arg1 arg2
Что вы ожидаете, это args [0] = c:\test \, а затем args [1] = arg1 и args [2] = arg2.
Следующая функция анализирует аргументы в списке с помощью этого упрощенного поведения.
Примечание. arg [0] - это имя программы, используя приведенный ниже код. (Вы вызываете List.ToArray(), чтобы преобразовать полученный список в массив строк.)
protected enum enumParseState : int { StartToken, InQuote, InToken };
public static List<String> ManuallyParseCommandLine()
{
String CommandLineArgs = Environment.CommandLine.ToString();
Console.WriteLine("Command entered: " + CommandLineArgs);
List<String> listArgs = new List<String>();
Regex rWhiteSpace = new Regex("[\\s]");
StringBuilder token = new StringBuilder();
enumParseState eps = enumParseState.StartToken;
for (int i = 0; i < CommandLineArgs.Length; i++)
{
char c = CommandLineArgs[i];
// Console.WriteLine(c.ToString() + ", " + eps);
//Looking for beginning of next token
if (eps == enumParseState.StartToken)
{
if (rWhiteSpace.IsMatch(c.ToString()))
{
//Skip whitespace
}
else
{
token.Append(c);
eps = enumParseState.InToken;
}
}
else if (eps == enumParseState.InToken)
{
if (rWhiteSpace.IsMatch(c.ToString()))
{
Console.WriteLine("Token: [" + token.ToString() + "]");
listArgs.Add(token.ToString().Trim());
eps = enumParseState.StartToken;
//Start new token.
token.Remove(0, token.Length);
}
else if (c == '"')
{
// token.Append(c);
eps = enumParseState.InQuote;
}
else
{
token.Append(c);
eps = enumParseState.InToken;
}
}
//When in a quote, white space is included in the token
else if (eps == enumParseState.InQuote)
{
if (c == '"')
{
// token.Append(c);
eps = enumParseState.InToken;
}
else
{
token.Append(c);
eps = enumParseState.InQuote;
}
}
}
if (token.ToString() != "")
{
listArgs.Add(token.ToString());
Console.WriteLine("Final Token: " + token.ToString());
}
return listArgs;
}
Ответ 5
В ответ на ответ WWC, Jamezor прокомментировал, что его код не сработает, если первый символ - это цитата.
Чтобы устранить эту проблему, вы можете заменить это событие StartToken следующим:
if (eps == enumParseState.StartToken)
{
if (rWhiteSpace.IsMatch(c.ToString()))
{
//Skip whitespace
}
else if (c == '"')
{
eps = enumParseState.InQuote;
}
else
{
token.Append(c);
eps = enumParseState.InToken;
}
}
Ответ 6
В чем именно проблема? Во всяком случае, здесь есть общий совет:
Убедитесь, что ваш метод Main (в Program.cs) определен как:
void Main(string[] args)
Затем args - это массив, содержащий аргументы командной строки.