Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Список child процессов


Автор: Purple_Light 8.8.2008, 12:56
Всем привет!

Вижу, что тема списка процессов уже поднималась, но у меня есть конкретная проблемма.

Есть процесс в системе, этот процесс может порождать детей. Перед тем как убить родительский процесс, необходимо пройтись по всем детям, которых он создал и завершить их. Вопрос как получить списов детей?

Поискал на форуме и нашел, только недокументированную функцию ZwQuerySystemInformation, но как написано на  MSDN она может меняться от версии к версии, что не есть хорошо  smile 

Может кто-нить поделится другим способом, если он существует.

З.Ы.: Система
Windows XP,
Windows 2000,
Windows 200* Server,
Windows Vista

Автор: Rrader 8.8.2008, 17:17
Могу посоветовать посмотреть в сторону WMI. Там есть класс Win32_Process. Его экземпляры - все процессы в системе. Что там есть интересного? Поле ParentProcessId ,в котором хранится ID породившего процесса (подобно th32ParentProcessID в ToolHelp). Т.е. проходимся по всем процессам, и если их ParentProcessId совпадает с требуемым - значит, дочерние. Их и закрываем. smile 

Код

instance of Win32_Process
{
    Caption = "ctfmon.exe";
    CommandLine = "\"C:\\WINDOWS\\system32\\ctfmon.exe\" ";
    CreationClassName = "Win32_Process";
    CreationDate = "20080807140324.671875+600";
    CSCreationClassName = "Win32_ComputerSystem";
    CSName = "RRADER-B1084D79";
    Description = "ctfmon.exe";
    ExecutablePath = "C:\\WINDOWS\\system32\\ctfmon.exe";
    Handle = "2272";
    HandleCount = 142;
    KernelModeTime = "57187500";
    MaximumWorkingSetSize = 1413120;
    MinimumWorkingSetSize = 204800;
    Name = "ctfmon.exe";
    OSCreationClassName = "Win32_OperatingSystem";
    OSName = "Microsoft Windows XP Professional|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
    OtherOperationCount = "245";
    OtherTransferCount = "4570";
    PageFaults = 9428;
    PageFileUsage = 1458176;
    // У меня это explorer.exe :)
    ParentProcessId = 1436;
    PeakPageFileUsage = 1462272;
    PeakVirtualSize = "40996864";
    PeakWorkingSetSize = 5148672;
    Priority = 8;
    PrivatePageCount = "1458176";
    ProcessId = 2272;
    QuotaNonPagedPoolUsage = 5440;
    QuotaPagedPoolUsage = 45884;
    QuotaPeakNonPagedPoolUsage = 5760;
    QuotaPeakPagedPoolUsage = 47336;
    ReadOperationCount = "2";
    ReadTransferCount = "136";
    SessionId = 0;
    ThreadCount = 1;
    UserModeTime = "17812500";
    VirtualSize = "40460288";
    WindowsVersion = "5.1.2600";
    WorkingSetSize = "5124096";
    WriteOperationCount = "2";
    WriteTransferCount = "144";
};


Может есть способ и лучше. smile 

Автор: Rififi 8.8.2008, 17:30
http://www.alexfedotov.com/articles/killproc.asp

Автор: Riply 11.8.2008, 10:17
Цитата(Rrader @  8.8.2008,  17:17 Найти цитируемый пост)
Т.е. проходимся по всем процессам, и если их ParentProcessId совпадает с требуемым - значит, дочерние. Их и закрываем


Возможна ситуация, что ParentProcessId совпадает с требуемым, но на самом деле,
процесс не является дочерним. (и это случается отнюдь не раз в сто лет smile)
(Система может использовать "значения" освободившихся ID)
Для точного установления "родственных отношений", дополнительно к ParentId можно использовать,
например, время создания процесса. 
IMHO, это уже дает полную гарантию, что нашли именно тех, кого искали smile

Автор: Rrader 11.8.2008, 15:43
Riply, я не глядел в MSDN. smile  Вы правы smile 

Автор: Purple_Light 1.9.2008, 14:53
Спасибо за ответы. 

Rififi в этой статье, как раз приведен пример с недокументированной функцией.

Проблемма оказалась немного сложнее. Например, если рассмотреть случай, когда пользователь (который именно и создает дочернии процессы) запустит приложение запускающее само себя рекурсивно. Получится, к тому времени как программа получит слепок процессов системы, в системе появятся новые процессы (рекурсивно запущенная программа). Соответственно раз ID процессов не попали в слепок (snapshot) приложение их не убъет.

Вообщем алгортм придумать, так и не удалось. Пришлось переписывать приложение, отслеживать запускаемые процессы и объединять их в группы. http://msdn.microsoft.com/en-us/library/ms684161(VS.85).aspx

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)