简体   繁体   English

C# 中的文件系统观察程序

[英]Filesystem Watcher in C#

Currently I have a Windows Service which constantly monitors 4 folders.目前我有一个 Windows 服务,它不断监控 4 个文件夹。 I have used FileSystemWatchers to monitor folders.我使用 FileSystemWatchers 来监视文件夹。

But everytime a new folder is added, I have to uninstall the service add a new filesystemwatcher and then install the service.但是每次添加新文件夹时,我都必须卸载该服务添加一个新的文件系统观察器,然后安装该服务。

I am thinking to make it dynamic or db driven where I dont not have to uninstall and re-install the service every time the program needs to monitor a new folder.我正在考虑使其成为动态或数据库驱动的,每次程序需要监视新文件夹时我都不必卸载和重新安装服务。

How can I achieve this?我怎样才能做到这一点?

Thanks in advance.提前致谢。

You could use an XML configuration file that the application periodically reads and caches for new folders.您可以使用应用程序定期读取并缓存新文件夹的 XML 配置文件。 These would go in the app.settings file.这些将 go 在app.settings文件中。

<configuration>
    <appSettings>
        <add key = "FolderToWatch" value = "C:\SomeFolder\" />
        <add key = "FolderToWatch" value = "C:\SomeFolder\AnotherOne\" />
        <add key = "FolderToWatch" value = "D:\LastOne\" />
    </appSettings>
</configuration>

Use a config file to add your new locations.使用配置文件添加新位置。 Then all you should have to do is restart the service any time you add a new location to your config file.然后,您只需在向配置文件添加新位置时重新启动服务即可。

I would use an.xml file as @Yuck suggested, however, I would just watch the.xml file.我会按照@Yuck 的建议使用.xml 文件,但是,我只会看.xml 文件。 Load the.xml when the services starts and monitor the.xml file thereafter for changes;服务启动时加载.xml,之后监控.xml文件是否有变化; if the.xml file LastWriteTime changes, reload it.如果.xml文件LastWriteTime发生变化,重新加载。

Here you have a demo that uses XML with Linq2XML and has the check over the config file change:在这里,您有一个使用 XML 和 Linq2XML 的演示,并检查了配置文件的更改:

class Program
{
    static List<FileSystemWatcher> _watchers = new List<FileSystemWatcher>();
    static bool _shouldReload = false;

    static void WaitReady(string fileName)
    {
        while (true)
        {
            try
            {
                using (Stream stream = System.IO.File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    if (stream != null)
                    {
                        System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} ready.", fileName));
                        break;
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
            }
            catch (IOException ex)
            {
                System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
            }
            catch (UnauthorizedAccessException ex)
            {
                System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
            }
            Thread.Sleep(500);
        }
    }

    static void Main(string[] args)
    {
        var configWatcher = new FileSystemWatcher(Path.GetDirectoryName(Path.GetFullPath("config.xml")), "config.xml");
        configWatcher.Changed += (o, e) =>
        {
            lock (_watchers)
            {
                _watchers.ForEach(w => { w.EnableRaisingEvents = false; w.Dispose(); });
                _watchers.Clear();
            }

            _shouldReload = true;
        };

        configWatcher.EnableRaisingEvents = true;

        Thread t = new Thread((ThreadStart)(() => {
            while (true)
            {
                Thread.Sleep(5000); // reload only every five seconds (safety measure)
                if (_shouldReload)
                {
                    _shouldReload = false;
                    Console.WriteLine("Reloading configuration.");
                    WaitReady(Path.GetFullPath("config.xml"));
                    loadConfigAndRun();
                }
            }
        }));

        t.IsBackground = true;
        t.Start();

        loadConfigAndRun();

        Console.ReadLine();
    }

    static void loadConfigAndRun()
    {
        var config = XElement.Load("config.xml").Elements();
        var paths = from watcher in config select watcher.Attribute("Folder").Value;

        foreach (var path in paths)
        {
            var watcher = new FileSystemWatcher(path);
            watcher.Created += new FileSystemEventHandler(watcher_Changed);
            watcher.Changed += new FileSystemEventHandler(watcher_Changed);
            watcher.Deleted += new FileSystemEventHandler(watcher_Changed);
            watcher.Renamed += new RenamedEventHandler(watcher_Renamed);
            watcher.EnableRaisingEvents = true;
            _watchers.Add(watcher);
        }
    }

    static void toggleWatcher(string path)
    {
        var watcher = _watchers.FirstOrDefault(w => w.Path == path);

        if (watcher != null)
        {
            watcher.EnableRaisingEvents = !watcher.EnableRaisingEvents;
        }
    }

    static void watcher_Renamed(object sender, RenamedEventArgs e)
    {
        var watcher = sender as FileSystemWatcher;

        Console.WriteLine("Something renamed in " + watcher.Path);
    }

    static void watcher_Changed(object sender, FileSystemEventArgs e)
    {
        var watcher = sender as FileSystemWatcher;

        Console.WriteLine("Something changed in " + watcher.Path);
    }
}

This is the config.xml:这是 config.xml:

<?xml version="1.0" encoding="utf-8" ?>
<Watchers>
  <Watcher Folder="d:\ktm"></Watcher>
  <Watcher Folder="c:\windows"></Watcher>
</Watchers>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM