|
Как завершить дочерний процесс? | ☑ | ||
---|---|---|---|---|
0
Jump
15.11.13
✎
11:42
|
Ситуация такая -
Программа или скрипт А при работе в некоторый момент запускает консольную утилиту B (например wget), эта утилита работает как отдельный процесс. 1й вопрос - как эту утилиту B грохнуть из программы А? 2й и самый главный вопрос - можно ли как нибудь так извернуться, чтобы ежели кто внезапно прибъет программу А, то чтобы автоматом прибились все программы B, которые она стартанула. |
|||
1
Jump
15.11.13
✎
12:05
|
Апнем?
|
|||
2
Jump
15.11.13
✎
12:58
|
Апнем!
|
|||
3
User_Agronom
15.11.13
✎
13:00
|
ps ax
а потом kill :) |
|||
4
Jump
15.11.13
✎
13:02
|
(3)Извиняюсь что сразу не уточнил - под виндой надо.
|
|||
5
Torquader
15.11.13
✎
23:28
|
WScript.Shell - там есть запуск процесса, когда получаем указатель и можем проверить, а жив ли ещё процесс или "дать ему пинка".
http://msdn.microsoft.com/en-us/library/2f38xsxe(v=vs.84).aspx Ну, в общем, всё что надо для работы (только на потоках ввода-вывода обычно "виснет", если пытаться читать то, что ещё не написали в консоль. |
|||
6
Мизантроп
15.11.13
✎
23:41
|
//*******************************************
//PsList.JS //Вывод списка процессов Windows //******************************************* // Объявляем переменные var PsWMI, PsProcesses1, PsProcess1, PsList1, Mess1; var vbCritical=16; //Создаем экземпляр объекта WshShell var WshShell = WScript.CreateObject("WScript.Shell"); //Включаем обработку исключительных ситуаций try { //Соединяемся с WMI PsWMI=GetObject("winMgmts:"); } //Начинаем обработку возможных ошибок catch (e) { if (e!=0) { Mess ="Ошибка\nКод ошибки: " + err.Number; WshShell.Popup(Mess,0,"Запущенные прoцеccы",vbCritical); WScript.Quit(); } } //Создаем кoллeкцию всех работающих процеccoв PsProcesses1=new Enumerator(PsWMI.ExecQuery("SELECT * FROM Win32_Process")); PsList1="Зaпущенныe прoцеccы\n\n"; //Цикл для перебора коллекции while (!PsProcesses1.atEnd()) { PsProcess1=PsProcesses1.item (); PsList1+=PsProcess1.Name + " " + PsProcess1.ProcessID + "\n"; PsProcesses1.moveNext(); } //Выводим кoллeкцию процеccов и их идентификаторов WScript.Echo(PsList1); //************* Конец ******************** |
|||
7
Мизантроп
15.11.13
✎
23:42
|
то же на VB
'********************************************** ' PsList.VBS 'Вывод списка процессов Windows '********************************************** ' Включаем обработку исключительных ситуаций On Error Resume Next ' Объявляем переменные Dim PsWMI, PsProcesses, PsProcess, PsList, Mess ' Создаем экземпляр объекта WshShell set WshShell = WScript.CreateObject("WScript.Shell") ' Производим соединение с WMI set PsWMI=GetObject("winmgmts:") ' Проверка на ошибку If Err.Number <> 0 Then Mess ="Ошибка" &vbCrLf & "Код ошибки: " & err.Number WshShell.Popup Mess,0,"Зaпущенныe процеccы",vbCritical Else ' Производи SQL запрос для получения кoллeкции set PsProcesses=PsWMI.ExecQuery("SELECT * FROM Win32_Process") PsList="Зaпущeнные проoцeссы" & vbCrLf & vbCrLf ' Производи перебор For Each PsProcess in PsProcesses PsList=PsList & PsProcess.Name & vbTab & PsProcess.ProcessID & vbCrLf NEXT 'Выводим список прoцесcов их идентификаторов WScript.Echo PsList End if '*************Конец*************************************** |
|||
8
Мизантроп
15.11.13
✎
23:42
|
потом tasklist
|
|||
9
Мизантроп
15.11.13
✎
23:43
|
можно вывод tasklist.exe парсить
|
|||
10
BigHarry
16.11.13
✎
11:40
|
Поскольку процессы запускаются как независимые, а не дочерние, то для того, что бы их идентифицировать и привязать к запускателю "А" надо как-то шаманить с заголовком окна, ну а taskkill может убивать по названию заголовка окна. Для случаев, когда убили запускателя "А" и надо прибить всех его "дочек" потребуется отдельный процесс, который будет проверять наличие осиротелых "дочек"...
|
|||
11
Torquader
16.11.13
✎
13:33
|
(10) В Windows информация о "дочерности" процесса теряется после его запуска (если родитель не использует режим отладки). Если мы знаем, кого мы запустили, то мы должны получать Id или HANDLE процесса - иначе мы его не найдём.
|
|||
12
N1kMZ
16.11.13
✎
14:11
|
(11) А как тогда Process Explorer от Sysinternals определяет "дочерность"?
|
|||
13
Torquader
16.11.13
✎
14:14
|
(12) Также как и обычный Windows mstask - если процессы запущены в одной консоли, то пока один исполняется, остальные в цепочке запуска его ждут - но в этом случае нет никакого параллельного исполнения - понятно, что ожидающий завершения другого процесса процесс будет считаться родительским.
|
|||
14
N1kMZ
16.11.13
✎
14:17
|
(13) Не, ну я из тотал коммандер запустил excel. Process Explorer показывает, что excel является дочерним по отношению к тоталу. И работают они параллельно.
|
|||
15
N1kMZ
16.11.13
✎
14:40
|
(14) + Если посмотреть "свойства" excel в process explorer, то там сказано parent: TOTALCMD.EXE(72532)
|
|||
16
Torquader
16.11.13
✎
14:52
|
(15) Вообще написано, что если через Process Snapshort сделать снимок исполняемой системы, то потом можно посмотреть информацию о каждом процессе
lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0 ); http://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx Это называется "свинство" - в самой системе информация спрятана, что её не достанешь, а если сделать снимок - на те получите - то есть, оказывается, хранит. |
|||
17
Torquader
16.11.13
✎
14:54
|
В общем, когда я в Windows 2000 это хотел сделать - такого не было, а потом Microsoft, видимо, понял, что линейная таблица - это не есть хороший способ хранения информации о процессах (ну или кто-то из них Linux увидел, где это всегда было).
|
|||
18
N1kMZ
16.11.13
✎
14:55
|
(16) Только вот новый процесс после убийства родителя может получить его PID.
|
|||
19
Torquader
16.11.13
✎
15:14
|
(18) Скорей всего, если PID занят, то второй раз его не дадут - но - нужно проверять.
|
|||
20
Torquader
16.11.13
✎
15:59
|
В общем - в ответе Microsoft сказано, что никто не отслеживает дерево процессов, а Id записывается в момент вызова функции CreateProcess - так что потом может оказаться, что "родителем" стал тот, кто получил Id.
Если на процесс есть открытые ссылки HANDLE, то объект процесса живёт и хранит его код выхода, а Id никакой смысловой информации не несёт - и система даже и не знает, помнит ли кто-то Id или нет. При запуске процесса можно получить HANDLE на него - пока HANDLE не закрыт, информация о процессе будет доступна - и его всегда можно завершить вызовом TerminateProcess. |
|||
21
Torquader
16.11.13
✎
16:01
|
Кстати, если мы передаём пароль в командной строке при запуске, то строку можно получить через запрос данных процесса до тех пор, пока объект процесса жив - так что про это нужно помнить.
|
|||
22
Jump
16.11.13
✎
17:05
|
(7)Спасибо, пробую.
(11)Ну я так и понял вроде, что нет такого штатного метода чтобы контролировать запущенный процесс. Поэтому вроде один вариант, как в (7) перебирать все текущие процессы и искать нужный. |
|||
23
Jump
16.11.13
✎
17:08
|
(21)Да каких то супер требований по безопасности нет, ну максимум узнав пароль можно получить доступ на чтение на удаленном хосте, но какой смысл - проще дождаться работы программы и посмотреть эти данные когда они скачаются локально.
Что касается долговременного доступа - пароли меняются регулярно, собственно одна из задач программы которая стартует процесс получить актуальный адрес и пароль, и скормить его wget'у. |
|||
24
Мизантроп
16.11.13
✎
17:56
|
Jump, попробуй такой код. Он тебе должен отдавать ProcessID при запуске процесса. AppActivate еще может заголовок окна менять.
WshShell = Новый COMОбъект("WScript.Shell"); Процесс = WshShell.Exec ("lalala.exe"); Рез = WshShell.AppActivate(Процесс.ProcessID); |
|||
25
Jaap Vduul
16.11.13
✎
17:59
|
(19)
ParentProcessId Data type: uint32 Access type: Read-only Unique identifier of the process that creates a process. Process identifier numbers are reused, so they only identify a process for the lifetime of that process. It is possible that the process identified by ParentProcessId is terminated, so ParentProcessId may not refer to a running process. It is also possible that ParentProcessId incorrectly refers to a process that reuses a process identifier. You can use the CreationDate property to determine whether the specified parent was created after the process represented by this Win32_Process instance was created. |
|||
26
Мизантроп
16.11.13
✎
18:15
|
Set WshShell = CreateObject("WScript.Shell")
PID = WshShell.Exec("notepad.exe").ProcessID WshShell.AppActivate(PID) msgbox PID рабочий код. Показывает PID запускаемого процесса |
|||
27
Torquader
16.11.13
✎
23:43
|
(26) Ему это в (5) и предлагалось, только в не настолько разжеванном виде.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |