Bezdepbonusu7Программирование: статьи и ответы

Вопрос

CreateProcess - lpApplicationName против lpCommandLine

Автор вопроса: AndyОтветов: 3

Я использовал Win API CreateProcess, и мне было интересно, в чем разница между использованием lpApplicationName и lpCommandLine для аргументов и. только параметр lpCommandLine.

Например:

CreateProcess(NULL, L"C:\Path\To\Notepad.exe", L"C:\Path\To\File\To\Load.txt"... etc
CreateProcess(NULL, NULL, L"C:\Path\To\Notepad.exe C:\Path\To\File\To\Load.txt"... etc

Я предполагаю, что второй вариант, где используется только lpCommandLine, будет похож на открытие cmd.exe и запуск именно этой строки. Но как насчет первой строки, она загружает приложение и указывает аргументы командной строки по-другому?

Я просмотрел документацию MSDN для API, но, похоже, она не очень подробно описывает, что происходит, что могут содержать эти параметры, и это нормально, но я просто не понимаю, что я должен делать, когда есть есть несколько способов сделать это.

Обратите внимание: я знаю, что две строки примера могут не работать, так как для lpCommandLine требуется LPTSTR, а не LPCTSTR. Это просто для простоты понимания.

Большое спасибо за любую помощь!

Энди

  • Что заставляет вас говорить, что MSDN не объясняет подробно, что происходит? Вряд ли можно подробнее. В трех словах, lpApplicationName более или менее делает именно то, о чем вы просите, и ничего более, тогда как lpCommandLine добавляет много интерпретаций и магии (добавление расширений, поиск PATH и т. д.). И, как сказал Джон, часто лучший способ - использовать оба. Damon 18.04.2011
  • Хорошо, может быть, есть какая-то деталь, которую я не понял/пропустил в первый раз, но она все еще кажется мне немного двусмысленной. Andy 19.04.2011

c++parameterswinapiprocess

Ответы

Ответ 1 · рейтинг 4 · John

Рекомендуемый способ - использовать оба параметра. Если вы не укажете lpApplicationName, вы позволите Windows проанализировать lpCommandLine, чтобы определить имя приложения. Поскольку пробел является допустимым символом в именах файлов и каталогов, это может (в редких случаях) привести к запуску неправильного приложения. (например, если у вас есть c:\program.exe и вы запускаете программу из каталога c:\program files в Windows XP).

В обоих случаях вы должны использовать имя приложения в lpCommandLine, так как оно используется для вычисления Argv[0].

Ответ 2 · рейтинг 3 · Anders

Я никогда не использую lpApplicationName и всегда цитирую часть приложения lpCommandLine, в вашем примере я бы выполнил "C:\Path\To\Notepad.exe" "C:\Path\To\File\To\Load.txt" (цитирование всех путей, переданных в CreateProcess, является хорошей идеей). Простое использование lpApplicationName может вызвать проблемы с дочерними процессами, которые обращаются к argv[0], поэтому Я держусь подальше от этого.


<rant> Использование CreateProcess для чего-либо, кроме вас самих, может быть проблематичным, поскольку NT6+ может в любой момент решить, что выполняемая вами вещь требует прав администратора из-за прокладок совместимости приложений и/или обнаружения установщика, и тогда CreateProcess просто не работает. Если вам не нужно использовать отладку или отказаться от флагов задания, я бы предложил просто вызвать ShellExecute[Ex], чтобы быть в безопасности...</rant>

Ответ 3 · рейтинг 1 · karlphillip

Согласно MSDN, lpApplicationName является необязательным и может иметь значение NULL. В этом случае имя модуля должно быть первым токеном, разделенным пробелами, в строке lpCommandLine.

Если исполняемый модуль является 16-разрядным приложением, lpApplicationName должно быть NULL, а строка, на которую указывает lpCommandLine, должна указывать исполняемый модуль, а также его аргументы.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы