Различие среди “Консоли”, “cmd.exe”, “оболочки”?

Я не совсем уверен в различии среди консоли (в "консольном приложении окон"), cmd.exe, оболочка.

  • Я знаю, что cmd.exe является автономным процессом при выполнении, cmd.exe == оболочка? Таким образом, оболочка является просто процессом?
  • консоль == cmd.exe?
  • MSDN заявляет ProcessStartInfo. UseShellExecute == Истинные средства используют оболочку при запуске процесса, это означает, что процесс запускается все равно, поскольку я выполняю cmd.exe и запускаю программу от той командной строки? Какой смысл того, чтобы делать это? Процесс запустился, этот путь имеет свою собственную консоль?

Заранее спасибо.

9
задан smwikipedia 26 February 2010 в 06:24
поделиться

2 ответа

- MSDN говорит, что ProcessStartInfo.UseShellExecute = = True означает, что при запуске процесса используется оболочка, означает ли это, что процесс запускается точно так же, как я запускаю cmd.exe и запускаю программу из этой командной строки? Какой пункт это делать? Есть ли у процесса, запущенного таким образом, своя консоль?

На самом деле это работает так:

  • если UseShellExecute имеет значение false, приложение будет запущено с помощью API CreateProcess ; этот API позволяет указать множество параметров запуска, среди которых есть возможность перенаправить stdin/stdout/stderr, но запускает только исполняемые файлы. При попытке запустить файл (например, документ слова) с CreateProcess произойдет сбой, поскольку документы слов не являются исполняемыми файлами.
  • если UseShellExecute имеет значение true, процесс будет запущен с помощью API ShellExecateEx ; эта функция является той же функцией, которую использует Проводник Windows (« оболочка », по крайней мере в терминологии Microsoft) при двойном щелчке по файлу в папке; его главное преимущество в том, что он «умеет» запускать документы (открывая их связанными программами), ему известны папки-оболочки,... потому что он использует много средств оболочки. Однако у него есть некоторые основные недостатки: он довольно тяжел по сравнению с голым CreateProcess (потому что ему приходится выполнять много дополнительной работы), он не может открыть даже исполняемые файлы, если что-то не так с ассоциациями файлов/расширениями оболочки/... и не может перенаправить stdin/stdout/stderr. Не то чтобы теоретически это было бы невозможно: после того, как все ShellExecureEx внутренне вызывает CreateProcess; проблема в том, что она не раскрывает эту функцию.

Итак, два метода создания процесса действительно совершенно разные; класс Process выполняет большую работу по их сглаживанию, но функция, которая абсолютно не может быть воспроизведена с помощью функции ShellExecureEx, является перенаправлением потоков IO, так как она недоступна для функции ShellExecureEx и может быть включена только при запуске процесса через CreateProcess.

Другим вопросом является использование консоли запущенной программой. Консоль назначается/повторно используется в CreateProcess (фактически IIRC это связано с загрузчиком Windows PE, который проверяет требуемую подсистему в заголовке PE); правила создания/повторного использования консоли указаны здесь .

Если запущенное приложение является приложением GUI, консоли не создаются; с другой стороны, если запущено консольное приложение, оно повторно использует родительский процесс, если только он не указан в CreateProcess и не вызывает флаг CREATE_NEW_CONSOLE.По умолчанию этот флаг не указывается, но я не уверен, что делает ShellExecureEx с консольными приложениями, и у меня нет окна Windows для проверки. Я оставлю это как упражнение для читателя.: П


Дополнительные ответы

Привет, Маттео, другой вопрос. Если создать новый процесс как отдельный процесс, к которому не подключена консоль. Где сейчас процесс stdout? Куда идет вывод процесса? Отличается ли процесс от выхода консоли?

Мне непонятно, что вы имеете в виду. При запуске нового процесса с CreateProcess/ShellExecureEx консоль выделяется по мере необходимости, т.е., если exe является исполняемым файлом консоли (как указано в заголовке PE), Windows предоставляет ему консоль (которая является новой или родительской в зависимости от правил, указанных выше); если exe является приложением GUI, для него не выделяется консоль.

IIRC, для приложений GUI stdout/stdin/stderr являются просто битовыми ведрами, т.е. они не указывают на ничего полезного, и все IO для них отбрасываются; кстати, ничто не останавливает приложение графического интерфейса пользователя от выделения консоли и перенаправления ей собственных потоков std *.

Помните, что консоль, std-потоки Windows и std-потоки CRT - это три отдельных элемента. Консоль является просто интерфейсом, который для консольных приложений удобно привязать по умолчанию к потокам Windows std.

Потоки Windows std перенаправляются при указании перенаправления stdin/stdout/stderr в CreateProcess; можно получить дескрипторы с помощью функции GetStdHandle и перенаправить их с помощью SetStdHandle .

CRT stdin/stdout/stderr, наконец, являются еще одной абстракцией, построенной библиотекой времени выполнения C; по умолчанию они привязаны к потокам Windows std.

Все это обычно работает безупречно, и вам даже не нужно беспокоиться о разнице между потоками Windows std и потоками ЭЛТ; однако, когда вы начинаете думать о перенаправлении потоков, это различие становится важным.

Если поток stdout процесса отличается от выходных данных консоли, и Shell выполняет привязку этих 2 потоков для нас. Будет ли выход процесса скопирован из process.stdout в console.output? Является ли это эффективным?

Оболочка не участвует в этом процессе, является ядром, которое выполняет сантехнику, следуя инструкциям, используемым в CreateProcess (или впоследствии измененным внутри нового процесса с помощью других API). Для вашей производительности, с такой многоуровневой структурой, как эта, это единственный способ; и более того, копирующая часть (если это действительно копия, я подозреваю, что все дело только в передаче указателей вокруг) - это самая быстрая часть процесса, настоящее узкое место - живопись окна консоли/прокрутка/и т.д. Фактически, если вы хотите запустить консольное приложение, позволяющее производить данные с полной скоростью, вы обычно перенаправляете его стандартный вывод в файл или через канал.

Большое спасибо.Маттео Италия. Вы хороший совлер проблем.: D

Спасибо.:)

11
ответ дан 4 December 2019 в 14:28
поделиться

Насколько мне известно:
Оболочка: интерфейс для операционной системы и, в конечном итоге, ядра. это включает explorer.exe и cmd.exe
Консоль: вы создаете экземпляр консоли Win32. Это окно, которое выводит ваш Console.WriteLine
cmd.exe: интерпретатор командной строки Windows. он создает экземпляр консоли Win32

Дополнительная литература:
http://en.wikipedia.org/wiki/Win32_console [Консоль win32, консоль, которую вы используете, если вам не требуется графический интерфейс пользователя ]

3
ответ дан 4 December 2019 в 14:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: