FileSystemWatcher не срабатывает при использовании C ++ std :: ofstream - PullRequest
2 голосов
/ 09 июня 2009

Я пытаюсь добавить монитор журнала во внутреннюю утилиту тестирования для службы Windows, над которой я работаю. Сервис написан на C ++ (win32), а утилита - на .NET (C #)

Монитор журналов работает для многих других приложений C ++, которые я написал, но не для моего сервиса.

Единственное основное отличие, которое я вижу, состоит в том, что другие приложения используют более старый :: WriteFile () для вывода в журнал, тогда как в сервисе я использую std :: ofstream так:

std::ofstream logFile;
logFile.open("C:\\mylog.log");
logFile << "Hello World!" << std::endl;
logFile.flush();

Из моей утилиты я использую FileSystemWatcher так:

FileSystemWatcher fsw = new FileSystemWatcher(@"C:\", "mylog.log");
fsw.Changed += new FileSystemEventHandler(fsw_Handler);
fsw.EnableRaisingEvents = true;

Но для службы она никогда не получает никаких событий изменения при обновлении журнала. Я обнаружил, что любой пример кода с использованием FileSystemWatcher, с которым я сталкивался в сети, тоже имеет ту же проблему ... Но я знаю, что события должны быть доступны, потому что другие приложения мониторинга журналов (например, BareTail ) работают нормально с файлом журнала службы.

Я бы предпочел, чтобы код C # для утилиты работал так, чтобы она работала с чем угодно, но если мне придется изменить код регистрации для службы, я это сделаю. Кто-нибудь видит, что здесь происходит не так?

Ответы [ 6 ]

3 голосов
/ 09 июня 2009

Вы пробовали установить

        fsw.NotifyFilter = NotifyFilters.LastWrite;

или другие фильтры?

3 голосов
/ 09 июня 2009

Просто дикая догадка, но запускается ли утилита, когда служба фактически закрывает файл журнала? Причина, по которой я спрашиваю, состоит в том, что Windows может не обновлять метаданные файла при вызовах до std::ofstream::flush(), что также иногда происходит в некоторых реализациях виртуальной файловой системы в других операционных системах.

Я также проверю, имеет ли утилита соответствующие разрешения на доступ к файлу журнала, созданному службой. Если вы запускаете сервис от имени администратора, вам, возможно, придется запустить утилиту от имени того же пользователя.

2 голосов
/ 09 июня 2009

Две идеи:

Сначала убедитесь, что ваш FileSystemWatcher работает с полным доверием. Попробуйте установить это в методе, в котором вы инициализируете наблюдателя:

[PermissionSet(SecurityAction.Demand, Name="FullTrust")]

Например, см. Пример кода FileSystemWatcher.Filter в MSDN.

Если это не сработает, попробуйте открыть файл с помощью:

std::ofstream logFile;
logFile.open("C:\\mylog.log", ios::out, filebuf::sh_read);

Возможно, вы блокируете файл, что (по какой-то причине) не позволяет наблюдателю файловой системы увидеть изменения файла при вашей записи.

1 голос
/ 09 июня 2009

Работает ли это, если вы запускаете свой сервис как обычный старый exe? Может ли это быть проблемой с учетной записью пользователя?

0 голосов
/ 28 октября 2010

Я решил проблему, установив для параметра IncludeSubdirectories значение «true».

В каталоге, который я смотрю, нет подкаталогов, но это решило проблему ...

0 голосов
/ 18 июня 2009

Я действительно хотел иметь возможность выбрать один из предыдущих ответов в качестве «ответа», но все они помогли мне найти окончательное решение.

После большого количества проб и ошибок с каждым решением я обнаружил, что могу заставить его работать (без изменения кода ведения журнала C ++), установив для параметра NotifyFilter:

NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.CreationTime;

Я предполагал, что по умолчанию он будет искать все по умолчанию, но, очевидно, нет. В общем, я думаю, что фильтр, который помог ему больше всего, был "Размер". LastAccess работал лучше, но он не всегда собирал каждое изменение ... это зависело от того, когда наблюдатель был запущен. Но размер получил его, чтобы увидеть все изменения.

Спасибо всем за помощь всем! Поскольку я не мог выбрать только один ответ, я старался быть честным и постарался проголосовать за каждый из ваших ответов.

...