Добрый день!
Есть программа, которая создает сторонний процесс A и ожидает его завершения по описателю процесса на WaitForSingleObject. Процесс А в свою очередь создает процессы B и C и сам при этом завершается. После завершения процесса А я получаю возврат из функции ожидания. Вопрос в том, как мне дождаться завершения процессов A, B и С?
Через задание — не вариант, т.к. программа, которая создает процесс А может уже сама находиться в задании из которого не сможет выйти и включить дочерние процессы в другое задание.
Re: Ожидание завершения процесса и его дочерних процессов
Здравствуйте, Xsyst, Вы писали:
X>Добрый день! X>Есть программа, которая создает сторонний процесс A и ожидает его завершения по описателю процесса на WaitForSingleObject. Процесс А в свою очередь создает процессы B и C и сам при этом завершается. После завершения процесса А я получаю возврат из функции ожидания. Вопрос в том, как мне дождаться завершения процессов A, B и С?
Воткнуть в процесс A ожидание завершения процессов B и C ?
Re: Ожидание завершения процесса и его дочерних процессов
X>Добрый день! X>Есть программа, которая создает сторонний процесс A и ожидает его завершения по описателю процесса на WaitForSingleObject. Процесс А в свою очередь создает процессы B и C и сам при этом завершается. После завершения процесса А я получаю возврат из функции ожидания. Вопрос в том, как мне дождаться завершения процессов A, B и С? X>Через задание — не вариант, т.к. программа, которая создает процесс А может уже сама находиться в задании из которого не сможет выйти и включить дочерние процессы в другое задание.
Навскидку несколько решений, но все топорные:
1) Метод влоб. Toolhelp'ом периодически перечислять все живые процессы, проверяя их парентов. Метод требует _не закрывания_ хэндла на процесс A до окончания всей спецоперации, в противном случае его PID может реюзнуться и выйдет конфуз.
2) Запустить процесс А под каким нить спецюзером. Периодически проверять список всех процессов и если никого под этим юзером не осталось — значит, час настал.
3) Создать какой нить десктоп CreateDesktop'ом. Запускить процесс А на нем. Периодически проверять десктоп на существование OpenDesktop'ом. Минусы — не будет видать гуя (а может это плюс?), могут возникнуть различные проблемы если например процессы затребуют шелловский функционал или еще чего.
4) Проставить переменную окружения в себе. Ее отнаследуют все ваши дети и внуки (хотя могут и отказаться от "наследства" при желании). Периодически чекать процессы, роясь в их PEBах. По 5 балльной шкале злостного пользования недокументированным функционалом тянет балла на 2. Но потрахаться придеться.
5) Запустить процесс А под дебагом. Ловить дебажные ивенты создания процессов. Советую в процессах первым делом подчищать флажок PEB::BeingDebugged (в wow64 процессах — в обоих PEBах). Иначе хип будет работать в особом, тормозном режиме.
..подумаю, может еще чего добавлю, если конечно методы такого рода представляют интерес
Как много веселых ребят, и все делают велосипед...
Re: Ожидание завершения процесса и его дочерних процессов
Здравствуйте, boris_, Вы писали:
_>Здравствуйте, Xsyst, Вы писали:
X>>Добрый день! X>>Есть программа, которая создает сторонний процесс A и ожидает его завершения по описателю процесса на WaitForSingleObject. Процесс А в свою очередь создает процессы B и C и сам при этом завершается. После завершения процесса А я получаю возврат из функции ожидания. Вопрос в том, как мне дождаться завершения процессов A, B и С?
_>Воткнуть в процесс A ожидание завершения процессов B и C ?
Не вариант, программа вообще ничего не знает о процессах, создаваемых процессом А
Re[2]: Ожидание завершения процесса и его дочерних процессов
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Xsyst, Вы писали:
>>Вопрос в том, как мне дождаться завершения процессов A, B и С?
PD>Исходники всех программ есть ? можно править ?
Нет, A, B и С — сторонние программы
Re[2]: Ожидание завершения процесса и его дочерних процессов
Здравствуйте, ononim, Вы писали:
X>>Добрый день! X>>Есть программа, которая создает сторонний процесс A и ожидает его завершения по описателю процесса на WaitForSingleObject. Процесс А в свою очередь создает процессы B и C и сам при этом завершается. После завершения процесса А я получаю возврат из функции ожидания. Вопрос в том, как мне дождаться завершения процессов A, B и С? X>>Через задание — не вариант, т.к. программа, которая создает процесс А может уже сама находиться в задании из которого не сможет выйти и включить дочерние процессы в другое задание.
O>Навскидку несколько решений, но все топорные: O>1) Метод влоб. Toolhelp'ом периодически перечислять все живые процессы, проверяя их парентов. Метод требует _не закрывания_ хэндла на процесс A до окончания всей спецоперации, в противном случае его PID может реюзнуться и выйдет конфуз.
Как вариант, но думал есть варианты попроще
O>2) Запустить процесс А под каким нить спецюзером. Периодически проверять список всех процессов и если никого под этим юзером не осталось — значит, час настал.
Не пойдет, процесс должен работать именно под текущим пользователем
O>3) Создать какой нить десктоп CreateDesktop'ом. Запускить процесс А на нем. Периодически проверять десктоп на существование OpenDesktop'ом. Минусы — не будет видать гуя (а может это плюс?), могут возникнуть различные проблемы если например процессы затребуют шелловский функционал или еще чего.
Для некоторых ситуаций как вариант. Спасибо.
O>4) Проставить переменную окружения в себе. Ее отнаследуют все ваши дети и внуки (хотя могут и отказаться от "наследства" при желании). Периодически чекать процессы, роясь в их PEBах. По 5 балльной шкале злостного пользования недокументированным функционалом тянет балла на 2. Но потрахаться придеться.
По моему 1-й вариант проще
O>5) Запустить процесс А под дебагом. Ловить дебажные ивенты создания процессов. Советую в процессах первым делом подчищать флажок PEB::BeingDebugged (в wow64 процессах — в обоих PEBах). Иначе хип будет работать в особом, тормозном режиме.
Тоже не пойдет, т.к. в принципе процессы B и C тоже могут создать дочерние процессы. Задача состоит в том, чтоб отследить момент завершения создаваемого процесса и всех его внуков, если таковые будут.
O>..подумаю, может еще чего добавлю, если конечно методы такого рода представляют интерес
Наверное можно еще сделать перехват CreateProcess и если эта функция вызывается в интересующем процессе, то передавать PID этого процесса ожидающей программе.
Re[2]: Ожидание завершения процесса и его дочерних процессов
[...] X>Наверное можно еще сделать перехват CreateProcess и если эта функция вызывается в интересующем процессе, то передавать PID этого процесса ожидающей программе.
Если пойдете по этому пути, то, помимо написания драйвера, можно воспользоваться WMI. Пример можно найти здесь..
Re: Ожидание завершения процесса и его дочерних процессов
O>>Навскидку несколько решений, но все топорные: O>>1) Метод влоб. Toolhelp'ом периодически перечислять все живые процессы, проверяя их парентов. Метод требует _не закрывания_ хэндла на процесс A до окончания всей спецоперации, в противном случае его PID может реюзнуться и выйдет конфуз. X>Как вариант, но думал есть варианты попроще
У него есть и большой недостаток — если как вы ниже написали процессы B и C могут порождать правнуков, которых тоже нужно ждать — то этот вариант — не вариант.
O>>4) Проставить переменную окружения в себе. Ее отнаследуют все ваши дети и внуки (хотя могут и отказаться от "наследства" при желании). Периодически чекать процессы, роясь в их PEBах. По 5 балльной шкале злостного пользования недокументированным функционалом тянет балла на 2. Но потрахаться придеться. X>По моему 1-й вариант проще
Зато этот сработает с правнутками.
O>>5) Запустить процесс А под дебагом. Ловить дебажные ивенты создания процессов. Советую в процессах первым делом подчищать флажок PEB::BeingDebugged (в wow64 процессах — в обоих PEBах). Иначе хип будет работать в особом, тормозном режиме. X>Тоже не пойдет, т.к. в принципе процессы B и C тоже могут создать дочерние процессы. Задача состоит в том, чтоб отследить момент завершения создаваемого процесса и всех его внуков, если таковые будут.
Ну так — дебажить надобно всех.
O>>..подумаю, может еще чего добавлю, если конечно методы такого рода представляют интерес X>Наверное можно еще сделать перехват CreateProcess и если эта функция вызывается в интересующем процессе, то передавать PID этого процесса ожидающей программе.
Сделать перехват, и сделать перехват, работающий стабильно на различных системах — это проблемы разных порядков. Особенно если это перехват CreateProcess'а.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Xsyst, Вы писали:
X>Добрый день! X>Есть программа, которая создает сторонний процесс A и ожидает его завершения по описателю процесса на WaitForSingleObject. Процесс А в свою очередь создает процессы B и C и сам при этом завершается. После завершения процесса А я получаю возврат из функции ожидания. Вопрос в том, как мне дождаться завершения процессов A, B и С?
А запускает B.EXE и C.EXE.
Переименовываем B.EXE в XB.EXE, C.EXE в XC.EXE.
Пишем свои B.EXE, который запускает XB.EXE и С.EXE, который запускает XС.EXE
Или как-то иначе, если можно. Словом, сделать так, чтобы A вызывала B и C через наши промежуточные процессы.
Остальное дело техники. Например, B.EXE ждет окончания XB.EXE и , дождавшись, шлет сообщение Parent.EXE
With best regards
Pavel Dvorkin
Re[3]: Ожидание завершения процесса и его дочерних процессов
Здравствуйте, visual_wind, Вы писали:
_>[...] X>>Наверное можно еще сделать перехват CreateProcess и если эта функция вызывается в интересующем процессе, то передавать PID этого процесса ожидающей программе.
_>Если пойдете по этому пути, то, помимо написания драйвера, можно воспользоваться WMI. Пример можно найти здесь..
WMI может быть отключен.
В качестве альтернативы для ToolHelp-а предлагаю ловить EVENT_OBJECT_CREATE, только их будет много, и только если у процессов есть окна. Зато не надо по таймеру снимки делать, при этом снимки надо делать отдельно для 32 и 64 бит, а вот окна меж собой равны
Здравствуйте, ononim, Вы писали:
O>>>Навскидку несколько решений, но все топорные: O>>>1) Метод влоб. Toolhelp'ом периодически перечислять все живые процессы, проверяя их парентов. Метод требует _не закрывания_ хэндла на процесс A до окончания всей спецоперации, в противном случае его PID может реюзнуться и выйдет конфуз. X>>Как вариант, но думал есть варианты попроще O>У него есть и большой недостаток — если как вы ниже написали процессы B и C могут порождать правнуков, которых тоже нужно ждать — то этот вариант — не вариант.
Почему не вариант? Я же знаю PID процессов B и C, почему тогда к правнукам нельзя применить тот же метод?
O>>>..подумаю, может еще чего добавлю, если конечно методы такого рода представляют интерес X>>Наверное можно еще сделать перехват CreateProcess и если эта функция вызывается в интересующем процессе, то передавать PID этого процесса ожидающей программе. O>Сделать перехват, и сделать перехват, работающий стабильно на различных системах — это проблемы разных порядков. Особенно если это перехват CreateProcess'а.
А чем перехват CreateProcess отличается от перехвата другой функции?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Xsyst, Вы писали:
X>>Добрый день! X>>Есть программа, которая создает сторонний процесс A и ожидает его завершения по описателю процесса на WaitForSingleObject. Процесс А в свою очередь создает процессы B и C и сам при этом завершается. После завершения процесса А я получаю возврат из функции ожидания. Вопрос в том, как мне дождаться завершения процессов A, B и С?
PD>А запускает B.EXE и C.EXE.
PD>Переименовываем B.EXE в XB.EXE, C.EXE в XC.EXE.
PD>Пишем свои B.EXE, который запускает XB.EXE и С.EXE, который запускает XС.EXE
PD>Или как-то иначе, если можно. Словом, сделать так, чтобы A вызывала B и C через наши промежуточные процессы.
PD>Остальное дело техники. Например, B.EXE ждет окончания XB.EXE и , дождавшись, шлет сообщение Parent.EXE
Не вариант, я же не в курсе, что будут за процессы B и C и будут ли они вообще
Re[4]: Ожидание завершения процесса и его дочерних процессов
O>>>>Навскидку несколько решений, но все топорные: O>>>>1) Метод влоб. Toolhelp'ом периодически перечислять все живые процессы, проверяя их парентов. Метод требует _не закрывания_ хэндла на процесс A до окончания всей спецоперации, в противном случае его PID может реюзнуться и выйдет конфуз. X>>>Как вариант, но думал есть варианты попроще O>>У него есть и большой недостаток — если как вы ниже написали процессы B и C могут порождать правнуков, которых тоже нужно ждать — то этот вариант — не вариант. X>Почему не вариант? Я же знаю PID процессов B и C, почему тогда к правнукам нельзя применить тот же метод?
Потому что между интервалами проверок А и Б могут упасть с трубы B и C могут успеть запуститься, запустить правнуков и издохнуть, и к следующей проверке останутся только правнуки, которых вы упустите.
O>>>>..подумаю, может еще чего добавлю, если конечно методы такого рода представляют интерес X>>>Наверное можно еще сделать перехват CreateProcess и если эта функция вызывается в интересующем процессе, то передавать PID этого процесса ожидающей программе. O>>Сделать перехват, и сделать перехват, работающий стабильно на различных системах — это проблемы разных порядков. Особенно если это перехват CreateProcess'а. X>А чем перехват CreateProcess отличается от перехвата другой функции?
Тем что его чаще все всего и перехватывают. А в хуках самая большая сложность — дружно сосуществовать с другими хуками, некоторые из которых бывают весьма ущербны.
Кстати в качестве альтернативы хуков можно рассмотреть ключик App_InitDlls — но у этого способа куча своих недостатков — чтобы прописаться/выписаться нужны админские права, в новых виндах появляются танцы с бубном с подписями и вообще функционированием этого ключа.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Xsyst, Вы писали:
X>Не вариант, я же не в курсе, что будут за процессы B и C и будут ли они вообще
Будут ли вообще — не проблема, а насчет первого уточни. Выходит, A может запускать неизвестно из какого списка берущиеся B и C ? Или все же список кандидатов известен ? EXE-шники все же не зарождаются сами...
Здравствуйте, Pavel Dvorkin, Вы писали:
X>>Не вариант, я же не в курсе, что будут за процессы B и C и будут ли они вообще
PD>Будут ли вообще — не проблема, а насчет первого уточни. Выходит, A может запускать неизвестно из какого списка берущиеся B и C ? Или все же список кандидатов известен ? EXE-шники все же не зарождаются сами...
я так понял, процесс А — может быть любым(например, пользователь выбрал)?
Хотелось бы узнать у автора, какова цель? А то, может быть, решение совсем другое нужно.
Здравствуйте, CEMb, Вы писали:
CEM>Здравствуйте, Pavel Dvorkin, Вы писали:
X>>>Не вариант, я же не в курсе, что будут за процессы B и C и будут ли они вообще
PD>>Будут ли вообще — не проблема, а насчет первого уточни. Выходит, A может запускать неизвестно из какого списка берущиеся B и C ? Или все же список кандидатов известен ? EXE-шники все же не зарождаются сами...
CEM>я так понял, процесс А — может быть любым(например, пользователь выбрал)?
CEM>Хотелось бы узнать у автора, какова цель? А то, может быть, решение совсем другое нужно.
Процесс A действительно может быть любым, об остальных процессах программа вообще ничего не знает. Их в принципе может и не быть.
А процессы B и C просто для примера, тем более их действительно может создать сам процесс A (например скопировать из своего оверлея или распаковать архив во временную папку).
Как пример, посмотрите как запускается ProcessExplorer на x64 системах.
А задача: дождаться окончания определенной операции, начатой при запуске процесса А, а заканчивающейся при завершении процесса А и всех процессов, порожденных процессом А и его внуками (правнуками и т.д.).
Re[5]: Ожидание завершения процесса и его дочерних процессов
windows 8 уже 2 года как вышла Или досточтимый сэр собирается поддерживать официально убитую Windows XP или вот-вот заканчивающую цикл поддержки Windows 7?
Re[6]: Ожидание завершения процесса и его дочерних процессов
Здравствуйте, tlp, Вы писали:
X>>Вложенные Jobы ведь только в windows 8
tlp>ииии?
tlp>windows 8 уже 2 года как вышла Или досточтимый сэр собирается поддерживать официально убитую Windows XP или вот-вот заканчивающую цикл поддержки Windows 7?
я уже рассказывал историю, как пошёл продвигаться на одном очень крупном архиве, завёл ветку на форуме, написал текст, стал общаться с народом, в том числе, кто чем пользуется и почему. И в очередной вопрос "а чем оно хорошо?", собеседник мне ответил: "мне нравится, и на моей 95-й не тормозит" — "у тебя 95-я винда?!" — "да"
...моя программа на 95-й винде точно не работала, возразить мне было нечего...
Здравствуйте, Xsyst, Вы писали:
X>>>>Не вариант, я же не в курсе, что будут за процессы B и C и будут ли они вообще
PD>>>Будут ли вообще — не проблема, а насчет первого уточни. Выходит, A может запускать неизвестно из какого списка берущиеся B и C ? Или все же список кандидатов известен ? EXE-шники все же не зарождаются сами...
CEM>>я так понял, процесс А — может быть любым(например, пользователь выбрал)?
CEM>>Хотелось бы узнать у автора, какова цель? А то, может быть, решение совсем другое нужно.
X>Процесс A действительно может быть любым, об остальных процессах программа вообще ничего не знает. Их в принципе может и не быть. X>А процессы B и C просто для примера, тем более их действительно может создать сам процесс A (например скопировать из своего оверлея или распаковать архив во временную папку). X>Как пример, посмотрите как запускается ProcessExplorer на x64 системах. X>А задача: дождаться окончания определенной операции, начатой при запуске процесса А, а заканчивающейся при завершении процесса А и всех процессов, порожденных процессом А и его внуками (правнуками и т.д.).
А какова цель всего этого, если не секрет? Зачем дожидаться окончания всех дочерних процессов?
Здравствуйте, CEMb, Вы писали:
CEM>Здравствуйте, Xsyst, Вы писали:
X>>>>>Не вариант, я же не в курсе, что будут за процессы B и C и будут ли они вообще
PD>>>>Будут ли вообще — не проблема, а насчет первого уточни. Выходит, A может запускать неизвестно из какого списка берущиеся B и C ? Или все же список кандидатов известен ? EXE-шники все же не зарождаются сами...
CEM>>>я так понял, процесс А — может быть любым(например, пользователь выбрал)?
CEM>>>Хотелось бы узнать у автора, какова цель? А то, может быть, решение совсем другое нужно.
X>>Процесс A действительно может быть любым, об остальных процессах программа вообще ничего не знает. Их в принципе может и не быть. X>>А процессы B и C просто для примера, тем более их действительно может создать сам процесс A (например скопировать из своего оверлея или распаковать архив во временную папку). X>>Как пример, посмотрите как запускается ProcessExplorer на x64 системах. X>>А задача: дождаться окончания определенной операции, начатой при запуске процесса А, а заканчивающейся при завершении процесса А и всех процессов, порожденных процессом А и его внуками (правнуками и т.д.).
CEM>А какова цель всего этого, если не секрет? Зачем дожидаться окончания всех дочерних процессов?
Для синхронизации задач. Например задача 2 должна выполниться только строго после задачи 1, а задача 1 в свою очередь состоит из того, что процесс А должен выполнить свою работу.
Примеров можно множество придумать.
Re[7]: Ожидание завершения процесса и его дочерних процессов
CEM>я уже рассказывал историю, как пошёл продвигаться на одном очень крупном архиве, завёл ветку на форуме, написал текст, стал общаться с народом, в том числе, кто чем пользуется и почему. И в очередной вопрос "а чем оно хорошо?", собеседник мне ответил: "мне нравится, и на моей 95-й не тормозит" — "у тебя 95-я винда?!" — "да"
CEM>...моя программа на 95-й винде точно не работала, возразить мне было нечего...
Да понятно, конечно. ТС просто нигде не указал, какую ОС имеет в виду и пишет ли он шаровару, которая должна работать на утюге Windows NT 3.51/windows phone/windows CE.
Здравствуйте, Xsyst, Вы писали:
CEM>>А какова цель всего этого, если не секрет? Зачем дожидаться окончания всех дочерних процессов? X>Для синхронизации задач. Например задача 2 должна выполниться только строго после задачи 1, а задача 1 в свою очередь состоит из того, что процесс А должен выполнить свою работу. X>Примеров можно множество придумать.
Всё равно непонятно. Почему задача 2 ждёт задачу 1? Моя гипотеза: общие системные ресурсы (файлы, сетевые порты и прочее), тогда проще следить за доступом к этим ресурсам. Потому что кроме процессов, можно ещё CreateRemoteThread кому-нибудь сделать. >>>А, и тут сразу мысль ещё: при старте процесса 1 вставлять ему Mutex, а 2 сидит и ждёт этот Mutex. Плюс перехват CreateProcess и далее по рекурсии. Без перехвата можно успеть насоздавать детей от детей между снимками, а родителей перебить, так что потом будет неясно, кто кому ребёнок.