C# FileSystemWatcher 监视仅由当前系统完成的网络驱动器上的更改

Posted

技术标签:

【中文标题】C# FileSystemWatcher 监视仅由当前系统完成的网络驱动器上的更改【英文标题】:C# FileSystemWatcher watch changes on network drive which is only done by current system 【发布时间】:2018-07-14 23:27:58 【问题描述】:

我正在关注FileSystemWatcher 的this 示例,最重要的是,我创建了Windows 窗体应用程序,只要在Z 驱动器中创建并重命名任何.txt 文件,该应用程序就会打开。

我已经构建了控制台应用程序并部署到两个系统,两个系统都在监听同一个网络驱动器(我在两个系统中都将网络驱动器映射为 Z 驱动器)

但是,问题是每当我在网络驱动器中创建或重命名.txt 文件时,两个系统的表单都在打开,这是合乎逻辑的,因为两个部署的控制台应用程序都在侦听相同的位置。

但我的要求是“表格只能在该系统中打开 谁在执行创建或重命名 .txt 文件的操作。”

我有什么办法可以做到这一点,或者fileSystemWatcher 类甚至可以做到这一点吗?

这里是代码sn-p。

public class Watcher


    public static void Main()
    
        Run();

    

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public static void Run()
    
        string[] args = System.Environment.GetCommandLineArgs();


        FileSystemWatcher watcher = new FileSystemWatcher("Z:\\", "*.txt");
        watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
           | NotifyFilters.FileName | NotifyFilters.DirectoryName;
        watcher.IncludeSubdirectories = true;
        // Add event handlers.
        //watcher.Changed += new FileSystemEventHandler(OnChanged); //Fires everytime files is changed (mulitple times in copy operation)
        watcher.Created += new FileSystemEventHandler(OnChanged);
        watcher.Deleted += new FileSystemEventHandler(OnChanged);
        watcher.Renamed += new RenamedEventHandler(OnRenamed);

        // Begin watching.
        watcher.EnableRaisingEvents = true;

        // Wait for the user to quit the program.
        Console.WriteLine("Press \'q\' to quit the sample.");
        while (Console.Read() != 'q') ;
    

    // Define the event handlers.
    private static void OnChanged(object source, FileSystemEventArgs e)
    
        // Specify what is done when a file is changed, created, or deleted.
        Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
        Application.EnableVisualStyles();
        Application.Run(new Feedback.Form1(e.FullPath));//Here I am opening new form for feedback
    

    private static void OnRenamed(object source, RenamedEventArgs e)
    
        // Specify what is done when a file is renamed.
        Console.WriteLine("File: 0 renamed to 1", e.OldFullPath, e.FullPath);
        Application.EnableVisualStyles();
        Application.Run(new Feedback.Form1(e.FullPath));//Here I am opening new form for feedback
    

【问题讨论】:

【参考方案1】:

FileSystemWatcher可能通知你某事发生了,你可能也能推断出什么发生了,但不要指望它。在我(和others')的经验中,这是一个非常有限且不可靠的组件。因此,如果目标文件夹有可能发生中度争用,我会使用某种轮询解决方案而不是文件观察器。

也就是说,它不会告诉您 进行了更改。一旦你推断出 什么 发生了变化,你需要对“谁”部分采取额外的步骤。文件系统存储的信息非常稀疏,您不会找到任何源机器信息。您可以尝试将创建这些更改的文件共享映射到不同的用户,因为您可以从中推断出修改系统: Finding the user who modified the shared drive folder files.

如果这不是一个选项,其他解决方案要复杂得多。

如果您有权访问托管 Z 的服务器:您可以为该资源打开 file audit log 并从事件日志(事件 ID 4663 / 5145)中推断出机器是谁。在这种情况下,将记录源机器名称。如果是 Windows 服务器(目录属性/安全性/高级/审计),启用它应该是轻而易举的事,但读取和同步日志更复杂。

如果上述解决方案都不可行,您可以使用dokan 之类的方式实现用户空间文件系统来代理您的文件共享。源进程将映射到您的应用程序而不是文件共享,这样您就可以引发自己的事件或只是将详细的审核日志写入数据库或其他任何内容,然后将实际命令转发到文件共享。虽然非常昂贵且非平凡的解决方案。但可能很有趣。

【讨论】:

我想我必须找到另一种方法来做到这一点......感谢您的指导。【参考方案2】:

FileSystemWatcher 为您提供有关文件更改的通知。

如果您想使用文件系统进行唯一通知,您需要为每个实例创建一个独立的文件夹。

类似:

Z:\Machine1\

Z:\Machine2\

其他选项是检查谁是文件的所有者/创建者,但在域设置中可能非常复杂。

【讨论】:

以上是关于C# FileSystemWatcher 监视仅由当前系统完成的网络驱动器上的更改的主要内容,如果未能解决你的问题,请参考以下文章

C#:FileSystemWatcher - 多个监视文件夹问题

C#的FileSystemWatcher用法实例详解

c# 中的FileSystemWatcher问题

c# FileSystemWatcher如何处理多个文件?

C# 之 FileSystemWatcher事件多次触发的解决方法

当从不同的计算机进行更改时,C# FileSystemWatcher 不会在 Nas 文件系统上触发