使用C ++ std :: ofstream时,FileSystemWatcher不会触发

时间:2009-06-09 17:48:08

标签: c# c++ monitoring

我正在尝试将日志监视器添加到我正在处理的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 个答案:

答案 0 :(得分:3)

只是一个疯狂的猜测,但是当服务实际关闭日志文件时,该实用程序是否会触发?我问的原因是Windows可能没有更新调用std::ofstream::flush()的文件元数据 - 有时也会在其他操作系统的某些虚拟文件系统实现中发生。

我还将检查该实用程序是否具有访问该服务创建的日志文件的适当权限。如果您以管理员身份运行该服务,则可能必须以同一用户身份运行该实用程序。

答案 1 :(得分:3)

您是否尝试过设置

        fsw.NotifyFilter = NotifyFilters.LastWrite;

或其他过滤器?

答案 2 :(得分:2)

两个想法:

首先,确保您的FileSystemWatcher以完全信任的方式运行。尝试在初始化观察程序的方法上设置此项:

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

有关示例,请参阅MSDN上的FileSystemWatcher.Filter示例代码。

如果不起作用,请尝试使用以下方法打开文件:

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

可能是您正在锁定文件,这是(出于某种原因)阻止文件系统观察者在您的写入时看到对文件的更改。

答案 3 :(得分:1)

如果您将服务作为普通的旧exe运行,它是否有效?这可能是用户帐户问题吗?

答案 4 :(得分:0)

我真的希望能够选择之前的答案之一作为“答案”,但所有这些都有助于我找到最终解决方案。

在对每个解决方案进行了大量的试验和错误之后,我发现我可以通过将NotifyFilter设置为:

来使其工作(无需修改C ++日志代码)
NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.CreationTime;

我有点假设默认情况下它会默认搜索所有内容,但显然不是。一般来说,我认为帮助最多的过滤器是“大小”。 LastAccess工作得更好,但它并不总是接受每次更改......这有点取决于观察者何时启动。但是大小让它看到了所有的变化。

感谢大家的帮助!由于我不能只挑选一个答案,所以我试图公平,并确保对你的每一个答案进行投票。

答案 5 :(得分:0)

我通过将IncludeSubdirectories设置为'true'来解决问题。

我看的目录没有任何子目录,但这解决了问题......