Отличия CreateProcess и ShellExecute

Каковы основные различия между ними? Я хочу запустить только другой EXE-файл из моего (C++) приложения. Существуют ли какие-либо различия при наследовании сред, функций безопасности и т. д.?


person Samuel    schedule 25.05.2012    source источник
comment
Эту информацию можно найти в документах MSDN. Этот вопрос слишком расплывчатый и неконкретный для SO. Есть десятки вопросов, которые обсуждают оба, и вы не приложили абсолютно никаких усилий, чтобы исследовать это самостоятельно. (Подсказка: только один из них позволяет указать что-либо об окружающей среде, дескрипторах наследования и другой информации. Я оставлю это на ваше усмотрение, чтобы выяснить, какой из них.)   -  person Ken White    schedule 25.05.2012


Ответы (3)


Основное различие между CreateProcess и ShellExecute заключается в следующем: CreateProcess больше ориентирован на низкий уровень, а ShellExec на высокий уровень пользователя, который видит пользователя в проводнике.

Например, используя CreateProcess, можно использовать командную строку, длина которой больше MAX_PATH. Он имеет ограничение в 32 768 символов. Вы также можете использовать CreateProcess для запуска программы (если у вас достаточно прав) на другом рабочем столе Windows, например, на экране входа в систему.

Другой пример. Вы можете использовать ShellExecute, чтобы запустить панель управления или открыть любую программу, которая существовала на компьютере, например, для редактирования файла JPG. Таким образом, вы работаете с ShellExecute рядом с соответствующими действиями в проводнике Windows.

person Oleg    schedule 25.05.2012
comment
CreateProcess НЕ может запустить процесс, если путь к программе превышает MAX_PATH. Он может передавать длинные аргументы программе, которую можно запустить, но это другое. По сути, в настоящее время нет способа запустить программу, расположенную глубже, чем MAX_PATH (если только нет короткого эквивалента 8.3) - person nikos; 29.12.2016
comment
@nikos: можно использовать как lpApplicationName, так и lpCommandLine для указания программы с параметрами. Максимальная длина lpCommandLine ограничена 32 768 символами. Вы можете прочитать в документацию что если lpApplicationName имеет значение NULL, часть имени модуля в lpCommandLine ограничена символами MAX_PATH. Используя как не NULL lpApplicationName, так и lpCommandLine, можно указать часть модуля, длина которой больше, чем MAX_PATH. Я думаю, что нужно использовать префикс \\?\ в пути - person Oleg; 29.12.2016
comment
@nikos: Более того, начиная с Windows 10 версии 1607 ограничения MAX_PATH были удалены из общих функций файлов и каталогов Win32 (см. начальное объявление и документацию). - person Oleg; 29.12.2016
comment
@nikos: Во многих практических случаях можно использовать более простой обходной путь, чтобы начать сокращать длинный путь до другого, более короткого. Можно использовать GetShortPathName с входным путем, начинающимся с "\\?\", и получить более короткое имя, которое вы можете использовать вместо него. Это не то же самое, что я писал раньше, но полезно уменьшить более короткие пути к файлам. - person Oleg; 29.12.2016
comment
просто попробуй запустить действительно глубокую программу, потом скажи мне, если у тебя получится ;) Теория далека от практики. См. здесь дополнительные zabkat.com/blog/long-8.3-path-names. htm - person nikos; 31.12.2016
comment
@nikos: я не совсем понимаю вашу цель или ваш вопрос. Сейчас я не могу проводить тесты на старых операционных системах. Я изменил текст старого ответа, чтобы указать только длину lpCommandLine, чтобы уменьшить ненужное обсуждение. Если вам нужно создать процесс с программой с длинным путем, то я бы рекомендовал вам использовать RtlCreateUserProcess с RtlCreateProcessParameters. Возможно, вам потребуется дополнительно использовать NtResumeThread, NtWaitForSingleObject, RtlDestroyProcessParameters, RtlInitUnicodeStringRtlDosPathNameToNtPathName_U тоже будет полезно). - person Oleg; 31.12.2016
comment
@nikos: вам было бы легко создать демонстрацию, которая использует собственный API на основе кода. пример и этот. Если у вас возникнут проблемы, вы можете задать новый вопрос, и я опубликую соответствующий пример кода в своем ответе. - person Oleg; 31.12.2016
comment
Я попробовал ваш недокументированный материал (образец runnt), но все равно не пошел. Я попробовал простой EXE-файл с длиной пути 307 символов, и он не работает при вызове RtlCreateUserProcess, независимо от системной настройки LongPathsEnabled. На самом деле ваш образец не может даже запустить простой процесс :) - person nikos; 01.01.2017
comment
@nikos: Прежде всего, тебе следует сменить тон, если ты хочешь, чтобы кто-то помог тебе. Секунды, вы должны опубликовать отдельный вопрос, где вы более подробно описываете свои проблемы и ваши текущие попытки. Текущий старый ответ касается различий CreateProcess и ShellExec, и у вас есть еще один вопрос. - person Oleg; 01.01.2017
comment
Я не ищу ответа. Вы сделали неправильное утверждение выше, и я поправляю вас. Вы не можете запустить процесс › MAX_PATH, точка - person nikos; 02.01.2017

Основное отличие заключается в гибкости. ShellExecute проще в использовании, но не обладает большой гибкостью. CreateProcess неудобно использовать, но позволяет делать все что угодно.

Например, с помощью CreateProcess вы можете указать дескрипторы (каналы или файлы), которые будут использоваться для стандартных потоков ввода/вывода/ошибок в дочернем элементе. ShellExecute не дает вам возможности сделать это.

Вероятно, также стоит отметить, что, хотя ShellExecute может использоваться для непосредственного запуска исполняемого файла, его основное назначение — «выполнить» файлы документов — например, сказать ему «выполнить» «независимо от.html». ", и он запускает веб-браузер по умолчанию и загружает в него указанный HTML-файл. Вы также можете сделать это, используя CreateProcess, но для этого вы (обычно) начинаете с вызова FindExecutable, чтобы найти программу, связанную с рассматриваемым файлом данных, а затем выполняете ее, передавая файл данных в качестве параметра.

person Jerry Coffin    schedule 25.05.2012

CreateProcess возвращает дескриптор и идентификатор запущенного процесса и его основного потока в структуре PROCESS_INFORMATION

person lazy_banana    schedule 25.05.2012