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

C# FileSystemWatcher watch changes on network drive which is only done by current system

我正在关注 FileSystemWatcherthis 示例,在此之上,我创建了 windows 表单应用程序,只要创建任何 .txt 文件,该应用程序就会打开并在 Z 盘重命名。

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

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

But my requirement is " The form should be opened in that system only who is performing the action of creating or renaming that .txt file."

Is there any way I can achieve this Or is this even possible with fileSystemWatcher class?

这是代码片段。

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
    }
}

FileSystemWatcher 会在文件更改时通知您。

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

类似于:

Z:\机器1\

Z:\机器2\

其他选项是检查谁是 owner/created 文件,但在域设置中它可能非常复杂。

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

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

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

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

如果上述 none 解决方案可行,您可以使用类似 dokan 的方法实现用户 space 文件系统来代理您的文件共享。源进程将映射到您的应用程序而不是文件共享,这样您就可以引发自己的事件或将详细的审计日志写入数据库或其他任何内容,然后将实际命令转发到文件共享。虽然非常昂贵且不平凡的解决方案。不过应该很好玩吧。