Как обойти ограничение длины командной строки? - PullRequest
17 голосов
/ 27 мая 2010

Я работал над небольшой и простой программой, в которую я перетаскиваю файлы, и, в соответствии с определенными правилами, они перемещаются в разные места.

Программа работает нормально, если я не удаляю больше нескольких файлов, а затем выдает ошибку (которая кажется больше Windows, чем что-либо другое), что команда запуска "c: \ myapp.exe \ file \ file \ file" "слишком долго.

Я понимаю, что могу настроить фоновый процесс, но я действительно предпочел бы, чтобы эта программа не запускалась в фоновом режиме (где она будет простаивать большую часть времени).

Есть ли способ обойти это ограничение?

Ответы [ 9 ]

14 голосов
/ 19 июня 2010

Если вы хотите удалить файлы в соответствии с Windows Explorer, то вы можете реализовать свои собственные обработчики удаления как обработчики расширений оболочки, см.

Вкл. Полное идиотское руководство по написанию расширений оболочки вы найдете хорошее введение в то, как писать такие расширения.

часть VI дает пример Drop Handler (для немного другого случая использования, но это не имеет значения).

Что касается Drop Shell Extension Handler, ваша программа получит полную информацию обо всех удаленных файлах, и вам не нужно запускать дочернюю программу со всеми файлами в качестве параметров, подобных командам.

14 голосов
/ 25 июня 2010

Из этого блога :

  • Максимальная длина командной строки для функции CreateProcess составляет 32767 символов. Это ограничение исходит из структуры UNICODE_STRING.
  • Если вы используете командный процессор CMD.EXE, то на вас также распространяется ограничение длины командной строки в 8192 символа, установленное CMD.EXE.
  • Если вы используете функцию ShellExecute / Ex, вы попадаете под ограничение длины командной строки INTERNET_MAX_URL_LENGTH (около 2048), наложенное функциями ShellExecute / Ex.
  • Максимальный размер вашей среды составляет 32767 символов. Размер среды включает все имена переменных плюс все значения.

Так что вам придется согласиться с некоторыми из упомянутых обходных путей (также есть другой обходной путь в блоге msdn, на который я ссылался).

2 голосов
/ 25 июня 2010

Я думаю, что обработчик перетаскивания может быть одним из способов, но он кажется довольно тяжелым.

Альтернативным решением является использование обработчика контекстного меню Проводника. После этого вы бы выбрали все файлы, но не перетаскивали их, щелкните правой кнопкой мыши и выберите новый пункт меню «Отправить».

Когда пункт меню выбран, он передает список команд в вашу программу. Есть несколько способов сделать это:

  1. запустите вашу программу и подайте список файлов на стандартный ввод
  2. записать список файлов во временный файл и запустить вашу программу только с одним аргументом команды - временным файлом, содержащим список файлов для обработки. Файлы списков обычно имеют префикс «@» в командной строке, чтобы отличать их от обычных имен файлов.
1 голос
/ 09 сентября 2015

Как обойти ограничение длины командной строки? Запишите всю команду в командный файл, например, в "C: \ Users \ Johnny \ Documents \ mybatch.bat". Напишите его так же, как в cmd (не нужно ничего экранировать). Затем в своем коде просто вызовите этот файл:

strCmdText = "C:\\Users\\Johnny\\Documents\\mybatch.bat";

ProcessStartInfo ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + strCmdText);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = true;

Process.Start(ProcessInfo);
1 голос
/ 25 июня 2010

Команды Unix часто имеют один или два параметра, которые могут иметь неограниченную длину. Некоторые из этих команд имеют добавленные параметры, которые могут получать эти аргументы из файла или из стандартного ввода. Таким образом, у вас есть одна команда, которая генерирует список аргументов и либо передает их во временный файл, либо передает их в стандартный вывод.

См. Также xargs, который может принимать список аргументов и вызывать вашу команду со всеми параметрами или в пакетах.

1 голос
/ 25 июня 2010

У меня возникла похожая проблема, когда я пытался получить подробности о безопасности на длинном пути. Мое решение состояло в том, чтобы отображать диски всякий раз, когда длина пути становится слишком большой. Проверьте мое решение на Как мне получить информацию о безопасности для длинного пути?

1 голос
/ 29 мая 2010

Я думаю, что самое простое решение - это изменить приложение, чтобы оно принимало каталог в качестве параметра, а не список файлов. Это позволит вам скопировать несколько файлов в один каталог. Затем вы можете перетащить папку на свой исполняемый файл. Затем он запускает команду типа «c: \ myapp.exe \ folder-with-files-in-it», которая не должна попадать в ограничение параметров командной строки, которое вы испытываете сейчас.

1 голос
/ 27 мая 2010

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

1 голос
/ 27 мая 2010

Я бы изменил приложение так, чтобы он брал файлы из определенного места (например, в определенной папке в файловой системе), а не указывал каждый файл в командной строке.

UPDATE:

Если требуется иметь возможность перетаскивать элемент в .exe через Windows Explorer, чтобы запустить приложение, как отметил Марк, тогда вы можете поместить все свои файлы в одну папку и удалить всю папку в .exe.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...