понедельник, 4 июля 2011 г.

Первое слово в командной строке является именем программы только по соглашению

Это перевод The first word on the command line is the program name only by convention. Автор: Реймонд Чен.

Формат командной строки, возвращаемой GetCommandLine = "программа аргументы", но это просто соглашение. Если вы передадите nil в параметр lpApplicationName функции CreateProcess, то CreateProcess будет считать первое слово (с учётом кавычек) в lpCommandLine именем программы. Однако если вы передадите значение в lpApplicationName, то именно эта строка будет определять, какую программу запускать, а строка из lpCommandLine для этого использоваться не будет.

Это означает, что если кто-то запустит вашу программу с такими параметрами к функции CreateProcess:
lpApplicationName  =  "C:\Path\To\Program.exe"
lpCommandLine  =  "slithy toves"
то когда ваша программа вызовет функцию GetCommandLine, она просто вернёт строку "slithy toves", которая не окажет вашей программе помощи по определению своего имени и местоположения.

Если вашей программе нужно определить своё собственное имя и местоположение, то она должа использовать функцию GetModuleFileName, как я уже отмечал ранее (прим.пер.: ParamStr(0) в Delphi всегда возвращает GetModuleFileName от 0 вместо использования командной строки для извлечения первого слова).

В чём смысл давать возможность указывать что-то отличное от имени запускаемой программы первым словом в командной строке? В Windows в этом не много смысла, хотя это часто используется в Unix, где вы можете запустить одну и ту же программу под разными "псевдонимами" (alias). Реально будет выполняться одна программа, но вы врёте ей о её имени и пишете другое имя в командной строке. Некоторые программы специально спроектированы, чтобы их можно было запускать таким образом для модификации их поведения, в зависимости от псевдонима, который им дают. К примеру, визуальный редактор работает в экранном режиме, если его имя указано как "vi", но переключается в строковый режим, если его имя - "ex".

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

К примеру, если вы забудете повторить имя программы в командной строке и запустите процесс так:
lpApplicationName  =  "C:\Path\To\Program.exe"
lpCommandLine  =  "arg1 arg2"
то когда ваша программа запустится, она проигнорирует arg1, потому что она думает, что это имя программы. Если это программа Delphi, то она воспримет параметры так:
ParamStr(0)  =  "C:\Path\To\Program.exe"
ParamStr(1)  =  "arg2"
Как я заметил ранее, большинство консольных программ проигнорируют первый аргумент, потому что будут думать, что это имя программы (в этом случае - псевдоним, но программа не знает об этом).

Аналогично, если это GUI программа, то она просто пропустит первое слово в командной строке, используя только arg2 как свой аргумент.

В чём был смысл этого обсуждения? Две вещи. Во-первых, если вы запускаете другие программы и явно задаёте lpApplicationName, то вам нужно не забыть продублировать имя программы в lpCommandLine. Иначе результаты вызова программы могут быть не те, что вы ожидаете. Во-вторых, вы (как программа) не должны использовать первый токен в командной строке для принятия решений по безопасности - потому что это слово контролируется вызывающим и может не иметь никакого отношения к реальности.

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.