Ш̴̴̜̥͍͕̼̙̱͙͎͍̘̀̐̔́̾̃͒̈̔̎́́͜р̧̛̺͖͖̯̖ͧͤ͋̅̽ͧ̈̐̽̆̐͋ͤͦͬ͛̃̑͞͞и̒ͥͤͯ͂ͣ̐̉̑ͫ̉̑҉̛͏̸̻͕͇͚̤͕̯̱̳͉ͅф̴̴̡̟̞͙̙̻͍̦͔̤̞̔̓́̍͗̚͢͞ͅт̨̐ͫ̂͊̄̃ͥͪ͏̫̺͍̞̼͈̩̥̜͔͜͜ы̸̴̱̺̼̠̦͍͍͍̱̖͔̖̱͉̅͑͌͒ͫ͒̀ͥ͐ͤ̅͘̕.̵̴̡̭̼̮͖͈̙͖͖̲̮̬͍͙̼̯̦̮̮ͦ̆̀̑̌ͮͧͣͯ̔̂́͟г͌ͮ̏̈͂ͯ̚҉̛̙̬̘̲̗͇͕̠̙͙̼̩͚̀͘͞ͅо̷̥̯̘̓ͤ̽͒̋̉̀̂̄̒̓̊ͨ͛́̌ͤ̂̀͠в̶̒͒̓̏̓̚҉̛̙̘̺̰̮̼̟̼̥̟̘̠̜͜н̸̷̸̲̝͈͙̰̟̻̟̰̜̟̗͎̻̻͍̿̔̃ͨ͑о̔̀̋ͫ̇̿̐ͫ͌͗ͩ҉̨̜̙̙͈͍̮̮̼̙̘̞̕͜͡ Войти !bnw Сегодня Клубы
У `CreateProcess(name, args, ...)` первым аргументом должен быть путь к исполняемому файлу а вторым параметры. Но ещё можно и путь и параметры задать вторым аргументом а первым передать нулл. Ещё можно задать и путь и параметры первым аргументом. Но если раскидывать на два, то параметры должны начинаться с пробельчика иначе будет какая-то ошибка.
#UD53ZZ / @mugiseyebrows / 972 дня назад

Ну, раз ошибка «какая-то», а не возвращаемая CreateProcess(), то подозреваю, что это вызываемая программа или какая-то стандартная библиотека в ней видит на нулевом месте в argv какую-то чепуху и сильно удивляется или пытается что-то с ней дальше делать, а пробельчик приводит к честному null.

#UD53ZZ/71T / @ceyt / 972 дня назад
@ceyt напиздел, будет не ошибка, а вызываемая программа не поймёт первый аргумент, по крайней мере с `cl.exe` так
#UD53ZZ/LQT / @mugiseyebrows --> #UD53ZZ/71T / 972 дня назад

@mugiseyebrows Это я намекаю, что первым аргументом надо повторить путь к файлу, потому что posix-программы ожидают, что при argc>0 там будет именно он, и только потом параметры, а не используют, скажем, GetModuleFileName().

#UD53ZZ/28A / @ceyt --> #UD53ZZ/LQT / 972 дня назад
я всегда думал что в спермовсе args парсит программа (или её либц), так что сожрется NUL-separated там или нужно SPC-separated зависит от хуесоса который её писал. нормально распаршенный в массив argv в винде - привиллегия, а не право.
#UD53ZZ/WZL / @stiletto / 971 день назад
@stiletto (жопой прочитал, в посте не было nul-separated, были пробельчики)
#UD53ZZ/NX8 / @stiletto --> #UD53ZZ/WZL / 971 день назад

@stiletto Я вчера посмотрел, это везде так: CreateProcess() в Win32, LoadModule() в Win16, exec*() в UNIX 80-х — везде можно написать что хочешь в качестве командной строки, а разбирать это будет указанная отдельным параметром вызываемая программа. (А вот DOS только голый кусок строчки между именем программы и символами перенаправления передаёт.) Busybox и все прочие именно так понимают, что за команду выполнять, да и в NT, по идее, файловые ссылки есть — загружать в память система будет реальный файл, а строчка останется. Кроме того, этим же путём можно вызвать оболочку с какими-то командами или запустить скрипт, указав при этом только строку, без имени обработчика (которое программа не хочет — или вообще не может — узнать). В общем, и такая комбинация иногда требуется, и сякая.

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

#UD53ZZ/KA4 / @ceyt --> #UD53ZZ/WZL / 971 день назад

@stiletto Мне кажется, пробел в начале приводит к argv[0] нулевой длины, то есть null, и поэтому оно прокатывает.

#UD53ZZ/M2Z / @ceyt --> #UD53ZZ/NX8 / 971 день назад
Вот что происходит: в `lpApplicationName` можно передать только полный путь к исполняемому файлу, если передать только имя идешь нахуй - оно не ищется ни в `PATH` ни в `cwd` ни рядом с файлом если передать аргументы тоже идешь нахуй в `lpCommandLine` можно передать имя или путь и аргументы А если использовать и `lpApplicationName` и `lpCommandLine` начинаются приколы, к исполняемому процессу придёт `argv` в котором `argv[0]` уже сразу первый аргумент а не имя файла, соответственно все приложеньки которые ассумят что `argv[0]` это имя файла проебут первый аргумент, поэтому прикол с пробелом работал [github](https://github.com/mugiseyebrows/test-create-process) [test1.log](https://github.com/mugiseyebrows/test-create-process/blob/main/test1.log) [test2.log](https://github.com/mugiseyebrows/test-create-process/blob/main/test2.log)
#UD53ZZ/MFC / @mugiseyebrows / 966 дней назад

@mugiseyebrows Никаких приколов, всё нормально и аналогично описанному в POSIX man exec(3). Системе предлагается запустить конкретный файл, если она может это сделать, остальные параметры регулируют какие-то детали процесса создания процесса. Одним из них является командная строка, то есть произвольная строчка, привязанная к прочим системным данным о процессе, и доступная ему. Есть она или нет, и что там будет написано — для запуска не важно. Может показаться, что система должна как-то разбирать её, склеивать одно с другим в соответствии с конкретной практикой, но это не так.

Во-первых, не все программы написаны на C или поверх C. Между собой через командную строку они могут общаться как угодно. Даже на C наполнение и значение параметров argc и argv определяется практикой, а не стандартом. Легко представить систему, в которой не существует никаких «путей» и «файлов программ» для подстановки в нулевой элемент, под которую пишут на C. С другой стороны, не труднее представить систему, в которой никакой «командной строки» в памяти не существует, а параметры main() конструируются libc по результатам вызова каких-то системных функций. Можно сказать, что программа, делающая что-то с argv[0], неявно требует задавать его в инструкции по использованию, только сегодня эта часть инструкции может лежать где-то в глубинах документации к компилятору или фреймворку.

Во-вторых, популярные операционные системы исторически поддерживают запуск процессов разнообразных подсистем. Легко представить поддержку не только привычных DOS, Win16, Win32, Linux и так далее, но и какой-нибудь экзотики, в которой командные строки выглядят как "abc$def/ghi". Добавлять в систему конструктор или конвертер командных строк для каждой подсистемы, который будет догадываться, что хотели сказать при вызове, — не лучшая идея. Кроме того, в разных системах модели соответствия между человекочитаемой строчкой и программным представлением могут отличаться. Как уже сказано, в DOS приложение получало не строку, а отдельно имя и параметры после разбора. Более того, для совместимости при указании первым или вторым параметром имён файлов их дескрипторы сразу записывались в специальные поля, чтобы программа ничего не разбирала, а сразу брала и читала-писала. Это, конечно, из времён килобайтов памяти и одной корневой директории на диске(те) пришло, и более сложно устроенными программами не использовалось.

В-третьих, одна и та же программа может по-разному работать, если её вызывать под разными именами, либо через манипуляцию с командной строкой, либо с помощью файловых ссылок. Функция, которая всегда использует имя файла, не позволит сделать такие вызовы.

Если же имя файла не задано, то системе предлагается просто обработать некий текстовый ввод. Можно было бы сделать как в system()/ShellExecute(), чтобы принималась и программа с параметрами, и команды оболочки, и какой-то скрипт, для которого она будет искать и запускать интерпретатор, и всё это с поиском имён файлов по директориям в PATH, но и имеющийся вариант поиска только приложений по началу строчки достаточно сложен. В MSDN всё это и описывается.

#UD53ZZ/51U / @ceyt --> #UD53ZZ/MFC / 965 дней назад
@ceyt Прикол заключается в том что нет краткой инструкции как действовать чтобы всё работало (документация говно). Вместо того чтобы написать: суды совать путь к файлу вместе с именем, суды совать название файла и аргументы, если путь не дадите будем искать в PATH, написано пять экранов постмодернистского текста деконструирующего программирование, виндовс, роль человека в истории и страшную тайну зеркал.
#UD53ZZ/EN2 / @mugiseyebrows --> #UD53ZZ/51U / 964 дня назад

@mugiseyebrows Заполняешь строчку ты, по своему разумению, разбирает строчку программа, по своему разумению, а система только перекладывает байтики и ничего по этому поводу не думает.

#UD53ZZ/QDT / @ceyt --> #UD53ZZ/EN2 / 963 дня назад
@ceyt Есть соглашение как это делать чтобы минимизировать wtf
#UD53ZZ/IJZ / @mugiseyebrows --> #UD53ZZ/QDT / 961 день назад
ipv6 ready BnW для ведрофона BnW на Реформале Викивач Котятки

Цоперайт © 2010-2016 @stiletto.