Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
АОПИ. Старое / АОПИ. Глава 2. Конспекты (02_04_19).rtf
Скачиваний:
65
Добавлен:
10.09.2019
Размер:
363.46 Кб
Скачать

§5. Синхронизация задач с помощью объектов ядра «уведомление об изменении» (Change Notification).

Уведомление об изменении — объект, который переходит в сигнальное состояние при изменении содержимого каталога на диске.

Функция создания объекта ядра «уведомление об изменении»

HANDLE FindFirstChangeNotification(

IN LPCSTR lpPathName,

IN BOOL bWatchSub,

IN DWORD dwNotifyFilter

);

Параметры и описание:

(1) lpPathName — определяет полный путь к каталогу для просмотра. Не может содержать относительный путь или пустую строку.

(2) bWatchSub — определяет отслеживание подкаталогов. Если TRUE, то функция отслеживает изменения в подкаталогах. Если FALSE, то отслеживает только в указанном каталоге.

(3) dwNotifyFilter — определяет фильтр изменений.

Принимает следующие значения:

FILE_NOTIFY_CHANGE_FILE_NAME (0x00000001) — любое изменение имени файла в наблюдаемом каталоге или поддереве. Изменения включают переименование, создание или удаление имени файла.

FILE_NOTIFY_CHANGE_DIR_NAME (0x00000002) — любое изменение имени каталога в наблюдаемом каталоге или поддереве. Изменения включают создание или удаление каталога.

FILE_NOTIFY_CHANGE_ATTRIBUTES (0x00000004) — любое изменение атрибута в наблюдаемом каталоге или поддереве.

FILE_NOTIFY_CHANGE_SIZE (0x00000008) — любое изменение размера файла в наблюдаемом каталоге или поддереве.

FILE_NOTIFY_CHANGE_LAST_WRITE (0x00000010) — любое изменение последнего времени записи файлов в наблюдаемом каталоге или поддереве.

FILE_NOTIFY_CHANGE_SECURITY (0x00000100) — любое изменение дескриптора безопасности в наблюдаемом каталоге или поддереве.

Возвращаемое значение.

Если функция завершилась успешно, она возвращает дескриптор объекта уведомления об изменении, в противном случае — возвращает INVALID_HANDLE_VALUE.

Описание.

При помощи функций ожидания (например, WaitForSingleObject) можно отслеживать указанный каталог или поддерево, используя дескриптор, возвращаемый функцией FindFirstChangeNotification. Когда одно из условий фильтрации «срабатывает» в отслеживаемом каталоге или поддереве, объект переходит в сигнальное состояние. После этого приложение может ответить на это условие и продолжить мониторинг каталога, вызвав функцию FindNextChangeNotification и соответствующую функцию ожидания. Когда дескриптор больше не нужен, его нужно закрыть с помощью функции FindCloseChangeNotification.

Функция перезапуска объекта ядра «уведомление об изменении»

BOOL FindNextChangeNotification(

IN HANDLE hChangeHandle

);

Параметры и описание:

(1) hChangeHandle — дескриптор уведомления об изменении, созданный функцией FindFirstChangeNotification.

Возвращаемое значение.

Если функция завершилась успешно, она возвращает TRUE, в противном случае — FALSE.

Функция остановки мониторинга дескриптора объекта ядра «уведомление об изменении»

BOOL FindCloseChangeNotification(

IN HANDLE hChangeHandle

);

Параметры и описание:

(1) hChangeHandle — дескриптор уведомления об изменении, созданный функцией FindFirstChangeNotification.

Возвращаемое значение.

Если функция завершилась успешно, она возвращает TRUE, в противном случае — FALSE.

Пример (C).

Программа ждет 15 секунд какого-либо события с невложенными папками диска C. Если событие происходит менее, чем за 15 секунд, то вывод сообщения на экран "Действие с папкой. Продолжить?", если же за 15 секунд ничего с папками не происходит, то программа завершается (время ожидания истекло).

После каждого события программа спрашивает пользователя о продолжении отслеживания. Если пользователь пишет "n" (нет), то программа завершается, иначе продолжает свою работу.

#include <stdio.h>

#include <locale.h>

#include <windows.h>

int main() {

setlocale(LC_ALL, "Russian");

HANDLE hChNotify = FindFirstChangeNotification("C:\\", FALSE, FILE_NOTIFY_CHANGE_DIR_NAME); /// Проверяем невложенные папки диска C

if (hChNotify == INVALID_HANDLE_VALUE) {

printf("Ошибка. Неверное значение дескриптора!");

return 1;

}

printf("Ждем изменений\n");

/// Ждем на протяжении 15 секунд. Если ничего не изменится, то выход из программы.

DWORD dwWaitNotify = WaitForSingleObject(hChNotify, 15000);

switch (dwWaitNotify) {

case WAIT_TIMEOUT : printf ("Время ожидания истекло\nВыход\n"); return 2;

}

while (true) {

printf("Действие с папкой. Продолжить?\n");

if (getchar() == 'n') /// Считываем первый символ

break;

while (getchar() != '\n') continue; /// Остальные пропускаем

if (!FindNextChangeNotification(hChNotify)) break;

printf("Ждем изменений\n");

/// Ждем на протяжении 15 секунд. Если ничего не изменится, то выход из программы.

dwWaitNotify = WaitForSingleObject(hChNotify, 15000);

switch (dwWaitNotify) {

case WAIT_TIMEOUT : printf ("Время ожидания истекло\nВыход\n"); return 2;

}

}

FindCloseChangeNotification(hChNotify); /// Закрываем

CloseHandle(hChNotify); /// Закрываем

Sleep(1000); /// Чуть-чуть поспим перед выходом

return 0;

}