Передача аргументов командной строки в C # - PullRequest
18 голосов
/ 17 марта 2009

Я пытаюсь передать аргументы командной строки в приложение C #, но у меня проблема с передачей что-то вроде этого

"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.

Любая помощь?

Ответы [ 6 ]

27 голосов
/ 17 марта 2009

Я только что проверил и проверил проблему. Это меня удивило, но это последний \ в первом аргументе.

"C:\Program Files\Application name\" <== remove the last '\'

Это требует большего объяснения, у кого-нибудь есть идея? Я склонен называть это ошибкой.


Часть 2, я провел еще несколько тестов и

"X:\\aa aa\\" "X:\\aa aa\" next

становится

X:\\aa aa\
X:\\aa aa" next

Небольшое действие Google дает некоторое представление из блога Джона Галлоуэя , основные правила которого:

  • Обратная косая черта является escape-символом
  • всегда экранировать кавычки
  • экранирование от обратной косой черты происходит только тогда, когда они предшествуют кавычке.
5 голосов
/ 17 марта 2009

Добавить ответ Яна Кемпа

Если ваша сборка называется «myProg.exe» и вы передаете в строке «C: \ Documents and Settings \ All Users \ Пуск Меню \ Программы \ Имя приложения» ссылку так

C:\>myprog.exe "C:\Documents and Settings\All Users\Start Menu\Programs\App name"

строка «C: \ Documents and Settings \ Все пользователи \ Пуск, Меню \ Программы \ Имя приложения»

будет в аргументах [0].

1 голос
/ 18 января 2011

В ответ на ответ 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;
                }
            }
1 голос
/ 05 мая 2010

Недавно я заметил ту же самую досадную проблему и решил написать синтаксический анализатор для синтаксического анализа массива аргументов командной строки.

Примечание: проблема в том, что аргументы .NET CommandLine, передаваемые статической функции void Main (string [] args), экранируются \ "и \\. Это сделано намеренно, поскольку вы, возможно, захотите передать аргумент, который имеет цитата или обратная косая черта в нем. Один пример:

скажем, вы хотите передать следующее в качестве одного аргумента:

-msg: Эй, "Где ты?"

например.

sampleapp -msg: "Привет, \" Где ты? в? \ ""

Будет, как отправить его с поведением по умолчанию.

Если вы не видите причин, по которым кому-либо приходится экранировать кавычки или обратную косую черту для вашей программы, вы можете использовать собственный синтаксический анализатор для анализа командной строки, как показано ниже.

IE. [program] .exe "C: \ test \" arg1 arg2

будет иметь аргументы [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;
}
1 голос
/ 17 марта 2009

Чтобы добавить к тому, что уже говорили все остальные, это может быть проблема побега. Вы должны избежать обратной косой черты с помощью другой обратной косой черты.

Должно быть что-то вроде:

C: \> myprog.exe "C: \\ Документы и настройки \\ Все пользователи \\ Меню" Пуск "\\ Программы \\ Имя приложения"

0 голосов
/ 17 марта 2009

В чем именно проблема? В любом случае вот несколько общих советов:

Убедитесь, что ваш метод Main (в Program.cs) определен как:

void Main(string[] args)

Тогда args - это массив, содержащий аргументы командной строки.

...