C# 用于监视文件夹/文件打开的FileSystemWatcher
我已经浏览过了,但是找不到任何关于我正在寻找的信息,如果有其他帖子已经讨论过了,那么我道歉 我正在寻求有关代码的帮助,这些代码将在其他人打开某个特定文件夹或打开该文件夹下的文件时监视该文件夹。此时,我可以看到用户何时打开和修改任何文件,但如果他们只是打开文件查看,即使我添加LastAccessed,它也不会引发事件。如有任何信息或帮助,将不胜感激 文件夹名为C:\Junk C#4.0中的代码: 你应该设置C# 用于监视文件夹/文件打开的FileSystemWatcher,c#,.net,wpf,filesystemwatcher,C#,.net,Wpf,Filesystemwatcher,我已经浏览过了,但是找不到任何关于我正在寻找的信息,如果有其他帖子已经讨论过了,那么我道歉 我正在寻求有关代码的帮助,这些代码将在其他人打开某个特定文件夹或打开该文件夹下的文件时监视该文件夹。此时,我可以看到用户何时打开和修改任何文件,但如果他们只是打开文件查看,即使我添加LastAccessed,它也不会引发事件。如有任何信息或帮助,将不胜感激 文件夹名为C:\Junk C#4.0中的代码: 你应该设置 watcher.Path = @"C:\junk"; 并删除watcher.Filter
watcher.Path = @"C:\junk";
并删除watcher.Filter
行(如果所有文件都应该触发事件)
使用属性可以为匹配的文件设置通配符,例如*.txt
即使我添加LastAccess,它也不会抛出事件
因为NotifyFilters.LastAccessed
指定要检索该属性,而不是要订阅的事件。可用的事件有已更改
、已创建
、或已删除
,这些事件都不是您想要的
您应该看看Win32函数,有文档记录。它可以被传递一个文件\u通知\u更改\u上次访问
标志,该标志似乎提供了您想要的:
对监视目录或子树中文件的上次访问时间的任何更改都会导致更改通知等待操作返回
编辑:忽略这一点,FileSystemWatcher
会在内部将NotifyFilters.LastWrite
作为int 32传递到FILE\u NOTIFY\u CHANGE\u LAST\u ACCESS
。我已经试过了,那个函数在文件访问时仍然不会通知
这可能是由于:
上次访问时间具有松散的粒度,只能保证时间精确到一小时以内。在Windows Vista中,我们已禁用对上次访问时间的更新,以提高NTFS性能。如果您使用的应用程序依赖于此值,则可以使用以下命令启用它:
fsutil behavior set disablelastaccess 0
要使此更改生效,必须重新启动计算机
如果在命令提示符下执行该命令,可能会写入LastAccess
,并触发事件。我不打算在我的SSD上尝试,也没有准备好VM,但在Windows 7上,disablelastaccess似乎是开箱即用的
如果禁用该行为后仍不起作用,请等待Raymond Chen(或他本人)的建议框出现,通常会有一个相当合理的解释,说明为什么文档似乎无法正确描述您遇到的行为。;-)
您也可以在循环中扫描目录并查看文件的LastAccessed属性。当用户打开某个文件时,您想做什么?您真正需要的是枚举和计时器,这样您就可以扫描目录并查看是否有任何文件处于打开状态。filesystemwatcher不会向您提供此信息要访问文件路径,有一种微型过滤器驱动程序解决方案。您必须实现minifilter驱动程序才能实现要求。Digvijay Rathore已经给出了答案,在我看来,这是唯一的好答案,即使有点太短
public void OnChanged(object sender, FileSystemEventArgs e)
{
string FileName = System.IO.Path.GetFileName(e.FullPath);
if(IsAvailable(System.IO.Path.Combine(RecievedPath,FileName)))
{
ProcessMessage(FileName);
}
}
private void ProcessMessage(string fileName)
{
try
{
File.Copy(System.IO.Path.Combine(RecievedPath,fileName), System.IO.Path.Combine(SentPath,fileName));
MessageBox.Show("File Copied");
}
catch (Exception)
{ }
}
private static bool IsAvailable(String filePath)
{
try
{
using (FileStream inputStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
{
if (inputStream.Length > 0)
{
return true;
}
else
{
return false;
}
}
}
catch (Exception)
{
return false;
}
}
我只想添加几句话和一个链接,感兴趣的用户可以从这里开始
FileSystemWatcher仅用于监视被监视文件夹中发生的事情,但无法监视和截获用户(或操作系统)正在做的事情
例如,使用FSW(FileSystemWatcher),您可以监视文件/文件夹何时以某种方式创建、删除、重命名或更改,并且这些事件在操作完成后释放,而不是在操作之前或期间
简单的FSW无法知道用户是否正在从受监视的文件夹启动可执行文件,在这种情况下,它将根本不生成任何事件
要在可执行文件启动之前捕获其启动时间(以及大量其他“事件”),并在可执行文件的代码加载到内存之前执行一些操作,您需要在较低(内核)级别编写一些内容,也就是说,您需要构建一个驱动程序,在本例中是一个(迷你过滤器)文件系统驱动程序
这是了解Minifilter Windows驱动程序基础的良好起点:
如果文件夹名为C:\JUNK,为什么不将其放在Path属性中?Filter属性用于筛选不包含的文件folders@Steve-根据您的建议,我更改了代码,但在打开文件夹时仍无法触发。请尝试使用文件系统筛选器驱动程序跟踪此类更改。其他变体不能很好地工作。为了快速完成这项工作,我只依赖NTFS安全审核层。我已经按照建议更改了代码,但在open上仍然没有触发器。首先尝试实现它…;)这似乎是一个皮塔,但这是另一个时间,因为现在我很高兴我有一条路要走。
public void OnChanged(object sender, FileSystemEventArgs e)
{
string FileName = System.IO.Path.GetFileName(e.FullPath);
if(IsAvailable(System.IO.Path.Combine(RecievedPath,FileName)))
{
ProcessMessage(FileName);
}
}
private void ProcessMessage(string fileName)
{
try
{
File.Copy(System.IO.Path.Combine(RecievedPath,fileName), System.IO.Path.Combine(SentPath,fileName));
MessageBox.Show("File Copied");
}
catch (Exception)
{ }
}
private static bool IsAvailable(String filePath)
{
try
{
using (FileStream inputStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
{
if (inputStream.Length > 0)
{
return true;
}
else
{
return false;
}
}
}
catch (Exception)
{
return false;
}
}