예제 #1
0
    public bool MonitorFolders(List <string> folders)
    {
        Log.Logger.Information("Monitoring folders ...");

        void ChangeHandler(object s, FileSystemEventArgs e)
        {
            OnChanged(e, this);
        }

        void RenameHandler(object s, RenamedEventArgs e)
        {
            OnRenamed(e, this);
        }

        void ErrorHandler(object s, ErrorEventArgs e)
        {
            OnError(e);
        }

        // Create file system watcher for each folder
        foreach (string folder in folders)
        {
            // Create a file system watcher for the folder
            Log.Logger.Information("Monitoring : {Folder}", folder);
            FileSystemWatcher watch = new();
            Watcher.Add(watch);
            watch.Path                  = folder;
            watch.NotifyFilter          = NotifyFilters.Size | NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watch.Filter                = "*.*";
            watch.IncludeSubdirectories = true;
            watch.Changed              += ChangeHandler;
            watch.Created              += ChangeHandler;
            watch.Deleted              += ChangeHandler;
            watch.Renamed              += RenameHandler;
            watch.Error                += ErrorHandler;
        }

        // Enable event watching
        Watcher.ForEach(item => item.EnableRaisingEvents = true);

        // Wait for exit to be signalled
        while (!Program.IsCancelled(1000))
        {
            // Lock and process the list of folders
            List <string> watchlist = new();
            lock (WatchLock)
            {
                if (WatchFolders.Any())
                {
                    // Remove root folders from the watchlist
                    //TODO : Maybe we need a way to not process sub-directories?
                    //foreach (string folder in folders)
                    //    WatchFolders.Remove(folder);

                    // Find folders that have settled down, i.e. not modified in last wait time
                    DateTime settleTime = DateTime.UtcNow.AddSeconds(-Program.Config.MonitorOptions.MonitorWaitTime);
                    foreach ((string key, DateTime value) in WatchFolders)
                    {
                        // If not recently modified and all files in the folder are readable
                        if (value < settleTime)
                        {
                            if (!FileEx.AreFilesInDirectoryReadable(key))
                            {
                                Log.Logger.Information("Folder not readable : {Folder}", key);
                            }
                            else
                            {
                                watchlist.Add(key);
                            }
                        }
                    }

                    // Remove watched folders from the watchlist
                    watchlist.ForEach(item => WatchFolders.Remove(item));
                }
            }

            // Any work to do
            if (!watchlist.Any())
            {
                continue;
            }

            // Process changes in the watched folders
            foreach (string folder in watchlist)
            {
                Log.Logger.Information("Monitored changes in : {Folder}", folder);
            }

            Process process = new();
            process.ProcessFolders(watchlist);
            Process.DeleteEmptyFolders(watchlist);
        }

        // Disable event watching
        Watcher.ForEach(item => item.EnableRaisingEvents = false);
        Watcher.Clear();

        return(true);
    }