![]() |
Модераторы: 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.
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "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. |