Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.11.07;
Скачать: [xml.tar.bz2];

Вниз

Дерево процессов.   Найти похожие ветки 

 
Leaner ©   (2004-09-30 15:26) [0]

Пытаюсь построить дерево процессов
при помощи CreateToolHelp32Snapshot.
Но иногда, правда очень редко, возникает такая ситуация:
1. Process1 создал Process2.
2. Process1 терминировался.
3. Process2 создает Process3 и ID третьего процесса совпадает с ID первого
В этом случае при создании дерева мы попадаем в бесконечный цикл.
Как можно этого избежать ?
P.S. Новый Snapshot не помагает: в ParentID второго указан ID третьего.


 
Digitman ©   (2004-09-30 15:37) [1]

что-то ты не то говоришь

CreateToolHelp32Snapshot делает мгновенный "снимок" списка работающих в этот момент процессов

идентификаторы процессов уникальны, поэтому изобразить дерево на основе ДАННОГО снимка не представляет никакого труда

после отображения дерева через время N ты вновь делаешь "снимок", который точно так же корректен как и первый снимок, но отражает уже иное состояние процессов .. и неважно что некий ID, фигурировавший ранее, был вновь задействован другим теперь процессом - дерево строится точно так же, но выглядеть оно будет уже по иному


 
Leaner ©   (2004-09-30 15:44) [2]

То, что это возникает - проверено на практике.
>идентификаторы процессов уникальны,
с этим никто не спорит, но
в ParentID второго указан ID третьего и он не меняется
при новом Snapshot
Эта ситуация сохраняется до тех пор, пока
существуют Process1 и Process2


 
Leaner ©   (2004-09-30 15:45) [3]

То, что это возникает - проверено на практике.
>идентификаторы процессов уникальны,
с этим никто не спорит, но
в ParentID второго указан ID третьего и он не меняется
при новом Snapshot
Эта ситуация сохраняется до тех пор, пока
существуют Process1 и Process2


 
Learner   (2004-09-30 15:47) [4]

Ошибся
не пока существуют Process1 и Process2,
а пока существуют Process2 и Process3


 
Digitman ©   (2004-09-30 17:15) [5]


> Learner


можно попробовать сделать так

определяем время старта Process2 и Process3
если Время2 < Process3, то это означает, что Process3 никак не может быть родителем Process2 - узел дерева добавляется в корень, а ссылка на "мертвого родителя" соответственно обнуляется


 
Leaner ©   (2004-09-30 18:11) [6]

>Digitman
А Вы не подскажите, как определить время старта просесса


 
Digitman ©   (2004-10-01 08:36) [7]

для win9x не подскажу

для NT-based систем следует открыть процесс (OpenProcess) и запросить инф-цию о нем (NtQueryInformationProcess в составе ntdll.dll), а еще лучше - перечислить процессы не средствами tlhelp32, а вызовом NtQuerySystemInformation с кодом класса инф-ции 5 (ф-ция возвращает блок структур TSystemProcessInformation, каждая структура содержит инф-цию о процессе, включая время создания)

пример :

type

 TUnicodeString = packed record
   Length, MaximumLength: Word;
   Buffer: PWideChar;
 end;

 PSystemProcessInformation = ^TSystemProcessInformation;
 TSystemProcessInformation = packed record
   dNext: DWord; //смещение начала следующей инф.структуре в блоке, последняя структура содержит в этом поле 0
   dThreadCount: DWord; //число активных трэдов процесса
   dReserved01, dReserved02, dReserved03, dReserved04, dReserved05, dReserved06: DWord;
   qCreateTime, qUserTime, qKernelTime: Int64;
   usName: TUnicodeString; //полное имя процесса (включая путь к исп.файлу)
   BasePriority: DWord; //приоритет
   dUniqueProcessId: DWord; // ID процесса
   dInheritedFromUniqueProcessId: DWord; //ID создателя
   dHandleCount: DWord; //число открытых описателей
   dReserved07: DWord;
   dReserved08: DWord;
   VmCounters: array[0..10] of DWord; //инф-ция о вирт.памяти
   dCommitCharge: DWord;
 end;

function NtQuerySystemInformation(sic: DWord; Buffer: Pointer; BufSize: DWord; var BytesReturned: DWord): DWord; stdcall; external "ntdll.dll";

function GetProcessCreationTime(ProcessId: DWord): Int64;
var
 p, Buf: PSystemProcessInformation;
 BufSize: DWord;
 TableSize: DWord;
begin
 Result := 0;
 BufSize := $10000;
 GetMem(Buf, BufSize);
 while NtQuerySystemInformation(5, Buf, BufSize, TableSize) <> 0 do
   begin
     Inc(BufSize, $10000);
     ReallocMem(Buf, BufSize);
   end;
 p := Buf;
 while True do
   begin
     if Buf.dUniqueProcessId = ProcessId then
       begin
         Result := Buf.qCreateTime;
         break;
       end;
     if Buf.dNext = 0 then Break;
     Inc(Integer(Buf), Buf.dNext);
   end;
 FreeMem(p);
end;


 
Внук ©   (2004-10-01 09:25) [8]

И все-таки см. Digitman ©   (30.09.04 15:37) [1].
По-крайней мере, у меня все работает корректно. Snapshot обновляется.


 
Игорь Шевченко ©   (2004-10-01 11:08) [9]

Leaner ©   (30.09.04 15:26)  

Для NT/Win2K/WinXP могу порекомендовать
http://www.schevchenko.net.ru/SRC/QuerySystemInformation_60.zip


 
Leaner ©   (2004-10-01 14:18) [10]

Всем огромное спасибо ! Попробую разобраться.
Но что делать с процессами, которые не открываются при помощи
OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,False,PID)  ?
У меня таких четыре ( кроме System ID=4, и Idle ID=0 )
ALG.EXE, CSRSS.EXE и два SVCHOST.EXE
Я получал время старта через GetProcessTimes.
>Внук
>у меня все работает корректно. Snapshot обновляется
Запусти из какой нибудь программы другую и терминируй первую.
Сделай Snapshot и посмотри, что записано в ParentID второй.


 
kaZaNoVa ©   (2004-10-01 14:28) [11]

Leaner ©   (01.10.04 14:18) [10]

>не открываются при помощи
> OpenProcess

- права админа есть ?


 
Leaner ©   (2004-10-01 14:31) [12]

>kaZaNoVa
>- права админа есть ?
Да.


 
kaZaNoVa ©   (2004-10-01 14:33) [13]

Leaner ©   (01.10.04 14:31) [12]
тогда не знаю .. должно работать ..
- раз уж WinLogon.exe открывается ....


 
Leaner ©   (2004-10-01 14:41) [14]

>kaZaNoVa
WinLogon.exe откривается
А, например, SVCHOST.EXE у меня четыре.
Два открываются, а два - нет.


 
Игорь Шевченко ©   (2004-10-01 14:44) [15]

Leaner ©   (01.10.04 14:41) [14]

Попробуй убрать PROCESS_VM_READ - для ряда процессов такой доступ запрещен.


 
Leaner ©   (2004-10-01 16:18) [16]

>Игорь Шевченко ©   (01.10.04 14:44) [15]
Попробовал: процессы, не отркывшиеся с
 PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
не открылись и без PROCESS_VM_READ


 
Игорь Шевченко ©   (2004-10-01 16:21) [17]

Leaner ©   (01.10.04 16:18) [16]

А GetLastError сообщил "Отказано в доступе" ?

Смирись, не судьба тебе их открыть. Если только не поробовать выставить привилегию отладки SeDebugPrivilege


 
Leaner ©   (2004-10-01 16:41) [18]

>Игорь Шевченко ©   (01.10.04 16:21) [17]
SeDebugPrivilege - помогло !
После стольких мучений все открылось.
Огромное всем спасибо ! Теперь буду эксперементировать.


 
Внук ©   (2004-10-02 13:59) [19]

Leaner ©   (01.10.04 14:18) [10]
Угу, тормознул, читал одно, а думал про другое. Такой эффект имеет место.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.11.07;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.051 c
4-1096437698
Gosha
2004-09-29 10:01
2004.11.07
Счетчик файлов


1-1098447134
eugene32
2004-10-22 16:12
2004.11.07
Как добавить индикатор прогресса в ячейку String Grid?


1-1098860642
snake1977
2004-10-27 11:04
2004.11.07
HTML


4-1096392758
Dunk
2004-09-28 21:32
2004.11.07
Обработчик сообщений необрабатывает события.


4-1096570172
redlord
2004-09-30 22:49
2004.11.07
блокировка файла





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский