![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Добрый день!
Необходимо решить следующую задачу: Имеются 2 консольных приложения, одно и которых при запуске меняет часть переменных среды и запускает второе приложение с заданными параметрами. Второе приложение должно взаимодействовать с вводом-выводом в консоль. На данный момент это реализовано через CreateProcess, при этом второму процессу передаются хэндлы ввода-вывода и в принципе все нормально отрабатывает. Но есть одно НО. При несанкционированном завершении родительского процесса, например через диспетчер задач, дочерний процесс остается висеть в памяти. Необходимо в идеальном случае замещать родительский процесс дочерним с сохранением взаимодействия с консолью в дочернем процессе. На данном этапе набросан черновик с использованием _execvpe, при вызове которого родительский процесс замещается дочерним. Возникла проблема с вводом-выводом в консоль из дочернего процесса. При запуске дочернего процесса, он выводит некоторую информацию в консоль, но при попытке пользовательского ввода с клавиатуры возникает ошибка:
После чего дочерний процесс висит в памяти но консоль с ним уже не связана. Кто-нибудь сталкивался с подобным или знает пути решения? Заранее спасибо! |
|||
|
||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Непонятно.
Не могли бы Вы дать параметры этого вызова.
_execvpe вызывает тот же CreateProcess, а потом exit(0)... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Через CreateProcess вызываю так:
|
|||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Можете показать реализацию _execvpe?
|
|||
|
||||
feodorv |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Вроде, всё на месте))) Поясните тогда, пожалуйста:
Дочерний процесс в конце концов не завершается самостоятельно, или же просто Вам хочется, чтобы он умирал синхронно со смертью родительского?
Почему тогда Почему не завершать родительский процесс сразу (ну, или после WaitForInputIdle)? Дочерний процесс теряет способность взаимодействия с консолью? Могу, но кода много и он относится к MSVS C++ 6.0. Добавлено через 1 минуту и 35 секунд Файл Execvpe.c
Добавлено через 2 минуты и 29 секунд Файл Execve.c
Добавлено через 3 минуты и 43 секунды Файл Spawnve.c
Добавлено через 6 минут и 17 секунд Остальное через 15 минут))) -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||
|
|||||||||||
alexx83 |
|
||||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
На работе вроде отправлял сообщение сюда что реализацию _execvpe нашел которую вы выложили. Все равно спасибо! Не нашел только реализацию функции comexecmd() - msdn ничего не нашел и в студии тоже не нашел.
Да нужно чтобы процессы умирали синхронно.
А можно по подробнее? После CreateProcess просто делать exit? |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Файл Dospawn.c
Добавлено через 8 минут и 13 секунд Это делается через job'ы. Из main (etc) можно просто return))) Или ExitProcess. exit - это как-то для stdlib. Но я бы предварительно сделал WaitForInputIdle на всякий случай... См. вышеприведённый файл Spawnve.c ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Если делаю так:
То получаю такой же результат как при использовании _execvpe, т.е. могу ввести только одну команду в консоли дочернему процессу и он отрубается от консоли |
|||
|
||||
alexx83 |
|
||||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Сделал через jobs:
Единственное если снимаю родительский процесс через менеджер процессов, то опять получаю:
Можно от этого избавиться? |
||||
|
|||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Даже не знаю, что сказать. Я бы ещё поэкспериментировал с флагом наследования, с GetConsoleProcessList() и т.д., но на всё это нужно время...
Опять-таки, не знаю, чем помочь... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: нет Всего: 110 |
feodorv, здравствуй.
уже и мне сабж любопытен. давай начнем сначала, а то я запутался... скажи, каким образом я могу запустить дочерний процесс так, чтоб он унаследовал дескрипторы стандартного ввода/вывода, и чтоб по завершению родительского процесса завершался дочерний? в линукс это решается банальным использованием fork() в родительском, и exec*() в дочернем. спасибо. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: нет Всего: 110 |
но в данном случае fork() лишний, да.
|
|||
|
||||
feodorv |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
boostcoder, здравствуй
![]() К сожалению, Windows - вещь в себе, и часто приходится искать неочевидные решения, использовать неочевидные опции (среди многочисленных подобных), чтобы добиться желаемого результата.
Это первая часть вопроса, не менее важная, чем вторая. Вот здесь сказано, что если при вызове CreateProcess (для консольного экзешника) не пользоваться флагами CREATE_NEW_CONSOLE и DETACHED_PROCESS, то дочерний процесс остаётся прикреплённым к консоли родительского процесса. Правда, я лично обычно всё же выставлял bInheritHandles в TRUE, а в STARTUPINFO устанавливал стандартные хендлеры не смотря на то, что это, вроде, и не требуется:
Почему всё-таки прописываю стандартные хендлеры в STARTUPINFO, хотя эта структура должна бы иметь смысл только при создании новой консоли.
Никак. Дочерний процесс в огромной степени независим от родительского, если не объединять их в "задания". alexx83 очень хорошо реализовал эту схему, да, с неприятным сайд эффектом... Вполне возможно, что смерть родительского процесса каким-то образом сказывается на консоли (т.е. отсоединяет от неё дочерний процесс), к сожалению, опыта работы с такими ситуациями нет. В принципе, если вся проблема в переменных среды, то можно как-нибудь исхитриться запускать только дочерний процесс через батник, в котором и выставлять или менять нужные переменные окружения. А может, дело в самом экзешнике дочернего процесса, как я понял, это gdb. Возможно, это он хитро реагирует на смерть родительского процесса. Добавлено через 4 минуты и 6 секунд Имеется в виду CREATE_NEW_CONSOLE. Добавлено через 10 минут и 39 секунд Ну, в принципе, можно организовать взаимодействие через пайпы, тогда при кончине родительского процесса дочерний процесс понимает, что пайп закрылся, и можно завершаться. Но это не наш случай, у нас стандартные хендлеры не переопределяются... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||
|
|||||||||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Сделал с заполнением хэндлов
Результат такой же как и без заполнения ![]() |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: нет Всего: 110 |
как я понял, семейство функций exec*() работает не так как в POSIX, хотя именно для этого эти функции и предоставляются msvcrt.dll.
|
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Многое не работает как в POSIX, а msvcrt.dll - это только лишь майкросовтовская реализация стандартной библиотеки, насколько можно приближенная к POSIX, но в общем и целом стандарту не соответствующая. Но! Майкрософт разработала специальную подсистему POSIX, в которой реализован стандарт, но в которой уже недоступны родные вызовы WinAPI. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: нет Всего: 110 |
||||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
Два раза прочитал, так и не понял, что нужно...
1.
То есть родитель вам больше не нужен. и он может благополучно завершиться, оставив работать дочерний? 2. мысль, перпендикулярная первой ![]() Нужно чтобы висели оба, причем родитель, исключительно для того чтоы при прибивании его, прибивался и дочерний? (больше от него проку то нет, все его функции замещены дочерним.)
Сформулируйте задачу четко. Тогда может и сами решите. А пока не сформулируете чётко, ее никто не решит. (и посикс тут не причем) Это сообщение отредактировал(а) volatile - 23.12.2012, 00:25 |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Нет, нет, всё понятно. Просто пытались рассмотреть разные возможности, поэтому такие несоответствия... Но всё неудачно ![]() А если всё таки запускать gdb (или что там) через bat-файл, в котором и выставлять нужные переменные окружения? Вот это ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
Ну раз все понятно, тогда видимо я недостаточно сообразителен. Посему, удаляюсь... ЗЫ: Хочу сказать только, что если первое, то делал неоднократно, и все прекрасно работало. Если второе не делал, потому как бессмысленно, но уверен что и это сделать можно. |
|||
|
||||
boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: нет Всего: 110 |
ну... я хз что в нем хитрого..gdb как gdb.
нужно попробовать. а можно взглянуть на фрагмент кода? ибо я сам проверял, и сабж невозможен. я больше склоняюсь к тому, что в вендус, вообще невозможно заменить родительский процесс дочерним. Добавлено через 9 минут и 35 секунд я вот только не понял, начиная с какой версии вендус предоставляется это? |
||||
|
|||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
boostcoder, я щас скомпилил тот код что приведен в этой теме. в этом посте:
У меня так: Ззапускается родитель. затем он запускает дочерний. затем родитель завершается. дочерний остается с той консолью, что была у родителя и полноценно работает и на ввод и на вывод. Все пашет. А вот зачем это мне не понять... ![]() |
||||
|
|||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Это вряд ли ![]() Вот этого не хотелось бы... Как раз хотелось бы Вашего участия...
Так и я о том же... Что-то здесь не так ![]() Как я понимаю всё же, gdb скомпилён в GNU окружении, эмулирующем поведение UNIX. И как там сказывается эта эмуляция - я хз)))
Как раз начиная с NT, какое-то там военное ведомство отказалось сертифицировать Windows NT без надлежащей поддержки POSIX. Изначально был реализован POSIX.1, сейчас число вызовов расширено (то ли 2000, то ли 3000 штук), но всё равно работа возможна только в текстовом режиме. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
В father.exe нажимаем 'f', запускается son.exe, father.exe завершаецца.
Для выхода нажимаем точку "." father.exe
son.exe
![]() Добавлено через 1 минуту и 41 секунду езешники father.exe, son.exe положить в одну папку. Присоединённый файл ( Кол-во скачиваний: 4 ) ![]() |
||||
|
|||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: нет Всего: 110 |
я размышляю привычными для меня терминами. в линукс, замещение процесса означает, загрузку другого процесса в адресное пространство первого. то, что описал ты, дает почти тот же результат. (я не говорю про наследование UID и GID)
это следствие того, что невозможен сабж, и приходится искать альтернативные способы достижения цели. нет. gdb умеет работать в нативной вендус среде. странно...впервые вообще слышу о такой штуковине. посмотрел экспорт dll`ки - да, экспортируются POSIX функции. Добавлено через 3 минуты и 44 секунды volatile, спасибо. завтра буду проверять. что-то уже и я запутался ![]() Добавлено через 7 минут и 16 секунд кто-то может подсказать, существуют ли вообще в открытом доступе исходники этой psxdll.dll? |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
так... этого в теме еще не было... В таком случае это еще и 3 альтернатива, того что нужно ТС... ![]() Имхо, здесь каждый говорит о своем, потому-что
|
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: нет Всего: 110 |
ладно, пусть сформулирует...
|
|||
|
||||
alexx83 |
|
||||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Спасибо что присоединились к этой теме volatile.
Задача проста: пишется враппер к gdb. Задача враппера изменить переменные среды и запустить gdb так чтобы он оставался привязанным к консоли в которой запущен враппер. Первый вариант - при этом враппер нам больше не нужен и он должен быть уничтожен. Второй вариант (если враппер не может быть уничтожен) - при завершении враппера должен завершаться и сам gdb. Для примера, вы работаете в IDE и запускаете приложение на отладку. Вместо самого gdb сначала запускается враппер который потом запускает gdb. IDE ничего не знает о враппере. По поводу вашего примера volatile. У меня от не работает как у вас на картинке ![]()
Может это глюк винды? |
||||
|
|||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
Естественно. Это же ваш код, взятый в этой теме. Я просто взял ваш код и показал что у меня он работает. alexx83, понятно, я попробую воссоздать баг, если удастся конечно. (я не пользуюсь gdb). По крайней мере, проблема прояснилась. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: нет Всего: 110 |
volatile, вот как у меня работают тобою предкомпилированные екзешники:
![]() Добавлено через 11 минут и 7 секунд win7, 64-bit. Добавлено через 13 минут и 24 секунды по выводу видно, что sun.exe запускается как отдельно введенная команда, а значит наследование дескрипторов не происходит. |
|||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
У boostcoder точно также работает как и у меня)) Volatile если есть возможность то вы попробуйте запустить ваши экзешники на компе без VisualStudio.
|
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
||||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
alexx83, хорошо. Ну а с Job' ами почему у вас не работает?
Собрал фазера, опять с вашим-же кодом (тем где Job' ы), и опять у меня все прекрасно работает. и даже из под грандфазера, и вообще из под чего-угодно.... Картинки постить не буду, уж поверьте на слово. запускаю фазер он запускает сына. сидят вместе. из менеджера закрываю фазера. сын автоматически закрывается сам. вот фазер, сына не менял. Добавлено через 1 минуту и 54 секунды вот Присоединённый файл ( Кол-во скачиваний: 4 ) ![]() |
|||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Да с jobами работает с одним неприятным моментом - когда завершается враппер то в консоли перед смертью gdb опять высакивает ошибка
|
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
||||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Вопрос по фазеру:
Почему заремили GetExitCodeProcess и "return exitCode" |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
||||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Ну типа да должен тихо уйти с миром)) |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
||||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Значит пока придется использовать вариант с jobами. Большое спасибо что уделил мне время) Если вдру придет еще что-нибудь в голову обязательно запостите сюда я готов перепробовать все варианты))
|
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
alexx83, в общем ваш вопрос сводится к несколько другой теме:
"Почему, при насильственном убиении процесса, он на что-то там успевает пожаловаться.." Это несколько другая тема, и упирается она в очередность прибивания системой хендлов убиваемого процесса. Воссоздать такой случай мне пока не удалось... Гадать на расстоянии трудно, тем не менее, попробуйте следующее: 1. Добавьте также текущий процесс в Job. (Фактически у вас в Job' е только дочерний). т.е: AssignProcessToJobObject (ghJob, GetCurrentProcess ()) (впрочем это врядли поможет). 2. Попробуйте во враппере, после создания дочернего, но перед WaitForSingleObject вставить отключение враппера от консоли. FreeConsole (); Возможно в таком случае убиение враппера, не будет вызывать жалобы gdb, на ошибки в stdin... |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
||||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
Большое спасибо! Как опробую отпишусь
![]() |
|||
|
||||
alexx83 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 29.3.2010 Репутация: нет Всего: 1 |
||||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
||||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |