ограничение параметра аргумента командной строки - PullRequest
9 голосов
/ 02 февраля 2012

Язык: C # Я должен передать огромный массив строк (созданный динамически) в качестве аргумента для запуска exe. Я думаю о достижении этого двумя способами ниже. Но я не чувствую себя уверенно.

  1. Я могу создать его как одну строку, разделенную пробелами. Я могу вызвать exe-файл через Process.Start. Следовательно, запущенный дочерний процесс считает пространство и хранит его как строковый массив. Однако я не уверен насчет ограничения массива строк. Предположим, что число строк моего массива превышает 10 000

  2. Я могу создать ее как одну строку, ограниченную специальным символом, который никогда не попадет в данные. Я могу вызвать exe со строкой. Запущенный дочерний процесс рассматривает его как одну единственную строку, где я могу разделить его с тем же разделителем, чтобы вернуть массив строк. Однако здесь я не уверен насчет размера команды. Будет ли это делать, если длина строки командной строки

Может ли кто-нибудь помочь мне сообщить мне ограничения размера параметра

Ответы [ 8 ]

18 голосов
/ 02 февраля 2012

Зависит от операционной системы:

См. Ограничение строки командной строки командной строки (Cmd. Exe) на сайте поддержки Microsoft.

Вкл.На компьютерах под управлением Microsoft Windows XP или новее максимальная длина строки, которую можно использовать в командной строке, составляет 8191 символов .На компьютерах под управлением Microsoft Windows 2000 или Windows NT 4.0 максимальная длина строки, которую можно использовать в командной строке, составляет 2047 символов .

(выделено мной)

Что касается размера строкового массива - если у вас много миллионов строк в строковом массиве - вы в основном ограничены объемом доступной памяти.

6 голосов
/ 02 февраля 2012

Хотя это плохая идея, Process.start с useshellexecute=false вызовет createprocess(), что позволяет использовать 32767 символов в командной строке (хотя это также максимальный размер для всего блока среды)

5 голосов
/ 02 февраля 2012

Если вы передаете 10000 аргументов в программу, вы должны поместить эти аргументы в файл и прочитать файл с диска.

3 голосов
/ 02 февраля 2012

Вы можете сохранить аргументы в текстовом файле и передать этот текстовый файл в качестве аргумента.Ваше приложение может затем проанализировать текстовый файл для анализа аргументов.

2 голосов
/ 02 февраля 2012

Не очень хорошая практика использовать аргументы командной строки для огромных массивов. Вместо этого поместите ваши аргументы в файл конфигурации и просто передайте имя файла в качестве аргумента командной строки.

Ограничение ОС зависит от версии Windows. Это может быть около 2 КБ или 8 КБ:

http://support.microsoft.com/kb/830473

1 голос
/ 02 февраля 2012

Вы можете рассмотреть возможность создания файла параметров и передачи файла в качестве параметра.

Я нашел это:

Для ОС: максимальная длина командной строки составляет 32767 символов (это ограничение из структуры строки Unicode), максимальная длина командной строки составляет 8192 символа (это ограничение из cmd.exe). Вы также можете проверить:

http://support.microsoft.com/kb/830473

Надеюсь, что это поможет.

0 голосов
/ 14 мая 2019

Если допустимо запускать дочерний процесс непосредственно из родительского процесса (UseShellExecute= false), то вы можете перенаправить StandardInput дочернего процесса и передать произвольный размер данных, выбросив его,Вот пример передачи массива из 100000 строк и прочего, сериализации в двоичном формате.

static void Main(string[] args)
{
    if (args.Length == 0)
    {
        var exeFilePath = Assembly.GetExecutingAssembly().Location;
        var psi = new ProcessStartInfo(exeFilePath, "CHILD");
        psi.UseShellExecute = false;
        psi.RedirectStandardInput = true;
        Console.WriteLine("Parent - Starting child process");
        var childProcess = Process.Start(psi);
        var bf = new BinaryFormatter();
        object[] data = Enumerable.Range(1, 100000)
            .Select(i => (object)$"String-{i}")
            .Append(13)
            .Append(DateTime.Now)
            .Append(new DataTable("Customers"))
            .ToArray();
        Console.WriteLine("Parent - Sending data");
        bf.Serialize(childProcess.StandardInput.BaseStream, data);
        Console.WriteLine("Parent - WaitForExit");
        childProcess.WaitForExit();
        Console.WriteLine("Parent - Closing");
    }
    else
    {
        Console.WriteLine("Child - Started");
        var bf = new BinaryFormatter();
        Console.WriteLine("Child - Reading data");
        var data = (object[])bf.Deserialize(Console.OpenStandardInput());
        Console.WriteLine($"Child - Data.Length: {data.Length}");
        Console.WriteLine("Child - Closing");
    }
}

Вывод:

Parent - Запуск дочернего процесса
Child -Запущено
Child - чтение данных
Parent - Отправка данных
Parent - WaitForExit
Child - Data.Length: 100003
Child - Закрытие
Parent - Закрытие

Этот пример выполняется на моей машине за 6 секунд.

0 голосов
/ 14 мая 2019
...