Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: WinAPI и системное программирование > Отследить активность приложения |
Автор: AVGu 5.5.2006, 15:21 |
Помогите разобраться в следующей ситуации: Имеется приложение для которого мне необходимо определить состояние, когда оно ожидает ввода от пользователя и в это время чтобы работало мое приложение. По сути что-то типа WaitFor...Object но проблема в том что запускает это приложение пользователь, а не моя задача то есть я не могу сделать у себя CreateProcess. Вторая проблема в том что основной модуль (exe) этой программы ничего кроме вызовов dll не делает а собственно вся работа в dll и выполняется, а поэтому (как я понимаю) нужно пользоваться WaitForMultipleObjects. Вот тут я и заткнулся (даже Рихтер не помогает, не говоря уж о DRKB ![]() ![]() ![]() Может быть есть какие-то другие способы определить состояние ожидания чужого приложения и всех его дочерних потоков? Подскажите направление, куда копать? |
Автор: Snowy 5.5.2006, 16:15 |
Если приложение ожидает ввода пользователя, то для этого оно должно быть активно. Точнее активно должно быть одно из его окон. То есть просто бери GetForegroundWindow и, если хэндл окна, принадлежит этому процессу, здачит он активен. Добавлено @ 16:16 Вот. Посмотри здесь: http://forum.vingrad.ru/index.php?showtopic=86044 |
Автор: AVGu 5.5.2006, 17:11 |
Snowy GetForegroundWindow - не совсем то что мне нужно. Плохо прописал исходные условия. Поясню подробнее. 1. Есть некая программа Prog.exe которая запускается пользователем. 2. Есть моя программа MyProg.exe, запускается им же. Задача моей программы MyProg.exe - эмуляция действий пользователя в программе Prog.exe - по сути там только нажать одну кнопку Process. То есть моя программа типа диспетчера, она готовит данные, она нажимает кнопки, ждет, опять готовит данные и т.д. Далее моя программа MyProg.exe должна "заснуть" пока Prog.exe обрабатывает данные, время обработки может изменяться от пары секунд до десятков секунд. Моя задача ждать пока Prog.exe отработает и перейдет к состоянию idle. Далее моя программа MyProg.exe снова готовит данные и эмулирует нажатие кнопки в программе Prog.exe ... та опять поехала работать а моя прога ждет. Так вот я не могу понять как отследить собственно момент завершения активности той второй программы и всех ее дочерних потоков. Все очень похоже на примеры из DRKB и прочих источников по реализации многопоточности но... потоки организую не я и не пойму как отследить активность или пассивность причем нескольких потоков. Как на картинке из ProcessExplorer (см вложение). Там у процесса/потока есть некое состояние State: Wait: UserRequest как то этот ProcessExplorer определяет что процесс в состоянии Wait....!? Как, не понимаю |
Автор: Rouse_ 5.5.2006, 17:58 | ||
Делается это примерно таким образом. NTQuerySystemInformation тип SystemProcessesAndThreadsInformation (пятерка). Получишь указатель на массив структур SYSTEM_PROCESS_INFORMATION. Последний параметр у каждой структуры будет указатель на массив структур SYSTEM_THREADS. У каждой этой структуры есть поле отображающее состояние State там находиться одно из следующих значений: StateInitialized, StateReady, StateRunning, StateStandby, StateTerminated, StateWait, StateTransition, StateUnknown (в порядке возрастания начиная с нуля) и WaitReason находящееся в одном из следующих значений: Executive, FreePage, PageIn, PoolAllocation, DelayExecution, Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, WrKernel, MaximumWaitReason (в порядке возрастания начиная с нуля) Пример как вся эта кухня работает бери тут: http://rouse.front.ru/taskmon.zip Добавь туда вот такой код:
Получишь информацию по главному потоку ![]() |
Автор: AVGu 5.5.2006, 18:50 | ||||||
Rouse_, огромное спасибо есть у меня и taskmon, но я его че то не могу запустить кстатиии у меня при компиляции ошибка вываливается
но в итоге у меня ничего не выводится и все...Delphi 5 у меня читал хелп по NTQuerySystemInformation а там в самом конце что-типа "к функциям нужно обращаться через GetProcAddres " во нашел цитату из MSDN
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/ntquerysysteminformation.asp ну ничего разберемся по любому спасибо за помощь ! Юмор в том, что я как вопрос в форум написал так и начал потихоньку разбираться с этими потоками. Я не учел одной вещи, того, что
выдает ВСЕ потоки, мне думалось так что если я засылаю pID конкретного процесса так мне и дадут снимок потоков для этого процесса, а оказывается нужно фильтровать по OwnerID! У Рихтера нашел пример! Дочитался таки |
Автор: Rouse_ 5.5.2006, 22:26 |
Ммм по поводу пятерки ничего не скажу, пример писался на семерке. По поводу GetProcAddres - не обязательно. Тут просто необходимо понимать под какую платформу идет приложение. Данный пример работает только под NT. |
Автор: AVGu 6.5.2006, 09:19 |
Rouse_, тогда вопрос, а то у меня сомнения закрались. Когда в документации идет упоминание о платформе NT имеется ввиду именно чистый NT или 2000 тоже. У меня 2000 Server а он же будто-бы продолжение классического NT!? Я правильно понимаю ситуацию или я ошибаюсь? А XP? Проясните пожалуйста. |
Автор: Rouse_ 6.5.2006, 10:55 | ||
|
Автор: AVGu 6.5.2006, 13:29 | ||
Rouse_ Под 2000 Server эта конструкция
возвращает в ReturnLength ноль! и в итоге taskmon ничего кроме CPU Usage не показывает. м.б. это как то связано с безопасностью и правами доступа? |
Автор: Rouse_ 6.5.2006, 16:22 |
Не в курсе - нет под рукой сервера 2000 чтобы протестировать. Так что пытайся разобраться сам... |
Автор: Rouse_ 6.5.2006, 16:50 |
Кстати попробуй обьявить не NtQueryXXX а ZwQueryХХХ, я просто не знаю как там в сервере шлюзы реализованы, если мое предположение верное, то должно помочь... |
Автор: AVGu 6.5.2006, 17:02 |
Rouse_, неа ни Zw ни Nt не катит, причем на 2000 Prof Workstation тоже, уже пробовал (я старые твои посты внимательно читаю ![]() разберусь! Нашел вот тут http://forum.sources.ru/index.php?showtopic=122553&hl=ntquerysysteminformation нашел ссылочку на http://dotfix.net/module.php?module=@6e786b366778716272736f6263706f5a5e5e6c5c597e787a там есть что-то по вызовам xxQuerySystemInformation для XP и 2000 не могу нигде найти описание для SYSTEM_INFORMATION_CLASS что там и как и еще вопрос Rouse_, у тебя в Taskmon SYSTEM_PROCESS_INFORMATION отличается от того, что описано в MSDN. Почему? Это результат препарирования системы или где-то есть информация полнее чем на Microsofte? |
Автор: Rouse_ 6.5.2006, 18:32 | ||||
А, кстати...
Это обычный перечислимый тип. Выглядит вот так:
|
Автор: AVGu 6.5.2006, 18:33 | ||
Rouse_, Понял
я так и думал ![]() еще вопрос если можно xxQuerySystemInformation возвращает значения одно из которых STATUS_INFO_LENGTH_MISMATCH. Подскажи пожалуйста какие еще могут быть значения или ссылочку на информацию. |
Автор: Rouse_ 6.5.2006, 18:44 | ||||
Вот тебе кусочек:
|
Автор: AVGu 22.5.2006, 11:32 | ||||||
Rouse_, спасибо огромное. Все получилось как нужно. Оказалось, что дочерние потоки передают родителю свое состояние. Таким образом я отслеживаю State и WaitReason для основного потока и все получается удачно. Пытаясь запустить твой демо Taskmon под W2K Server и под XP внес в него некоторые коррективы (идея не моя, подсмотрел http://dotfix.net/module.php?module=@6e786b366778716272736f6263706f5a5e5e6c5c597e787a ) вот откорректированные куски 1. Собственно объявление
в противном случае выдавалась ошибка 2. код в котором определяется необходимый объем памяти
3. Собственно вызовы
Еще раз огромная благодарность и мои извинения .... был в командировке не мог сразу ответить. |
Автор: Rouse_ 22.5.2006, 13:46 | ||
Угу, спасибо за корректировку, поэксперементировал и выяснилось что под ХР на запрос SystemProcessesAndThreadsInformation размер возвращается, но на запрос SystemHandleInformation уже переменная пуста. Как выяснилось, об этом упомянуто у Неббета...
|