четверг, 23 февраля 2012 г.

ProcessWatcher. Part 3.

      Ну а теперь я предлагаю кратко рассмотреть программный код. Хочу сразу предупредить: код писался примерно с такой же скоростью, с какой мысли, по поводу того, что и как я хочу видеть в окошке консоли, у меня появлялись. Т.е. другими словами никакого предварительного планирования архитектуры не производилось и к правомерности использования тех или иных функций должного внимания уделено не было. Через некоторое время стало ясно, что list - скорее всего был не лучший вариант, нужно будет немного подумать и переписать, если лень не сделает свое дело)). Ну и сам набор методов можно было спроектировать по другому, более универсально. Но всё это дело недалёкого будущего, пока у нас есть некоторая база, с ней и будем работать.

    В качестве базовой библиотеки, которая предоставляет нужный функционал для работы с процессами, используется Toolhelp API. Она располагается в tlhelp32.h. Немалая часть кода основана на примере, предложенном Джеффри Рихтером в его книге “Windows для профессионалов”.
   Ядром программы является класс CProcWatch:
class CProcWatch
{
private:
   HANDLE m_hSnapshot;
   list lstPeNew;
   list lstPeOld;
   PROCESSENTRY32 pe;
public:
   CProcWatch(void);
public:
   ~CProcWatch(void);
public:
   BOOL ProcNewSnapshot();
   BOOL ProcView();
   BOOL ProcWatchWork();
   BOOL ProcModuleView(short nProcNum);
   BOOL ProcModuleWatch(short nProcNum);
};
   Атрибутов в классе немного:
   HANDLE m_hSnapshot - снимок состояния системы;
   list <PROCESSENTRY32> lstPeNew - обновлённый список процессов;
   list <PROCESSENTRY32> lstPeOld – список процессов, полученный на предыдущем этапе;
   PROCESSENTRY32 pe – информация о процессе (каком-либо).
   Среди методов, наибольший интерес представляют:
   BOOL ProcView() - просмотр списка загруженных процессов;
   BOOL ProcWatchWork() - слежение за открывающимися и закрывающимися процессами;
   BOOL ProcModuleView(short nProcNum) - просмотр списка модулей процесса nProcNum;
   BOOL ProcModuleWatch(short nProcNum) - слежение за открывающимися и закрывающимися модулями процесса.
   Как оказалось тема изучения процессов Windows довольно интересная, особенно если есть для этого приемлемый инструмент.
   Для примера разберём код функции ProcNewSnapshot().
BOOL CProcWatch::ProcNewSnapshot()
{
   m_hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   BOOL prExist = Process32First(m_hSnapshot, &pe);
   if(prExist)
   {
      lstPeOld.clear();
      lstPeOld = lstPeNew;
      lstPeNew.clear();
   }
   if(prExist)
   {
      while(prExist = Process32Next(m_hSnapshot, &pe))
            lstPeNew.push_back(pe);
   }
   else return FALSE;
   return TRUE;
}
   Сначала мы делаем снимок нашей системы на уровне процессов, для этого вызываем функцию CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0). Первый аргумент TH32CS_SNAPPROCESS говорит о том, что мы хотим видеть процессы в нашем снимке. Второй аргумент равен нулю, т.к. в данный момент нас интересуют процессы, а не содержание, какого-то из них.
   После получения снимка, мы считываем информацию о первом процессе в нём. Для этого используется функция Process32First(m_hSnapshot, &pe). Первый аргумент – это непосредственно сам снимок, второй – структура PROCESSENTRY32, которая содержит нужные нам данные. Из всех атрибутов структуры, самыми интересными (для нас конечно) являются szExeFile – имя процесса и th32ProcessID – его идентификатор.
   После этого мы старый список процессов и формируем новый, используя функцию Process32Next.
   Теперь кратко рассмотрим работу остальных функций.
   BOOL ProcWatchWork().
   Эта функция следит за открытием и закрытием процессов. Если фиксирует такое событие, то выводит сообщение в консоль. По сути, она сравнивает старый и новый списки процессов и, если они отличаются, информирует нас об этом. Сравнение ведётся один раз в 10 мс. Это большой недостаток. По идее лучше ловить сообщения системы о том, что создан такой-то процесс и после этого выполнять необходимые действия. Такой подход менее затратный с точки зрения ресурсов. Но пока будем довольствоваться этим решением.
   BOOL ProcModuleView(short nProcNum).
   Эта функция выводит список модулей конкретного процесса. Номер процесса передаётся как аргумент. Важно отметить, что номер процесса в данном случае – это не его PID, а порядковый номер в lstPeNew. По PID в дальнейшем тоже можно будет обращаться.
   Для остальных функций код ещё не написан. В скором будущем должен появиться.
   Спасибо за внимание. Увидимся)))

Комментариев нет:

Отправить комментарий