2 votes

FileSystemWatcher en tant que service Windows avec Visual Studio 2019

Donc, j'ai créé un service Windows, où j'utilise un FileSystemWatcher pour surveiller différents répertoires. Chaque fois que des fichiers modifiés sont détectés, je les copie dans un répertoire différent, afin de pouvoir travailler avec eux plus tard.

Este fonctionne parfaitement lorsque je lance le programme en tant que Application Console .

Lorsque je l'exécute en tant que service Je peux démarrer et arrêter le service correctement mais il ne détectera aucun type d'événement. J'ai essayé de déboguer mon service et j'ai découvert que l'erreur provient du fait que je n'arrête pas la fonction FileSystemWatcher .

Pour mon application console, j'ai ce code pour l'objet Watch() méthode :

    public void Watch()
    {
        using (FileSystemWatcher watcher = new FileSystemWatcher($"C:\\Users\\wost\\AppData\\Roaming\\Sublime", _ext))
        {
            watcher.NotifyFilter = NotifyFilters.LastAccess
                                 | NotifyFilters.LastWrite
                                 | NotifyFilters.FileName
                                 | NotifyFilters.DirectoryName;

            watcher.IncludeSubdirectories = true;
            // Add event handlers.
            watcher.Changed += OnChanged;
            watcher.Created += OnChanged;
            watcher.Deleted += OnChanged;
            watcher.Renamed += 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') ;
        }
    }

Donc, j'arrête le programme si l'utilisateur appuie sur 'q'.

Pour mon service Windows, j'ai ce code pour la fonction Watch() méthode :

 public void Watch()
    {
        using (FileSystemWatcher watcher = new FileSystemWatcher($"C:\\Users\\lashi\\AppData\\Roaming\\Sublime Text 3", _ext))
        {
            watcher.NotifyFilter = NotifyFilters.LastAccess
                                 | NotifyFilters.LastWrite
                                 | NotifyFilters.FileName
                                 | NotifyFilters.DirectoryName;

            watcher.IncludeSubdirectories = true;
            // Add event handlers.
            watcher.Changed += OnChanged;
            watcher.Created += OnChanged;
            watcher.Deleted += OnChanged;
            watcher.Renamed += OnRenamed;

            // Begin watching.
            watcher.EnableRaisingEvents = true;

        }
    }

Donc, ici je n'arrête pas le FileSystemWatcher du tout, car comme je n'ai pas d'interaction directe avec l'utilisateur, je ne sais pas comment l'arrêter. Pouvez-vous m'aider à trouver une solution à ce problème ?

Ce sont les OnStart() y OnStop() méthodes :

public partial class Service1 : ServiceBase
{
    Watcher w;

    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart()
    {
        w = new Watcher($"C:\\EMMC_CACHE\\expt1-log", $"C:\\EMMC_CACHE\\expt1-file", "lashi");
        w.Watch();
    }

    protected override void OnStop()
    {
        DirectoryInfo dir = new DirectoryInfo(@"C:\Users\wost\Desktop\FILES");
        int count = dir.GetFiles().Length;
        // TEST
        if (count == 0)
        {
            StreamWriter writer = new StreamWriter(@"C:\Users\wost\Desktop\Notes.txt");
            writer.WriteLine("Service is stopped at: " + DateTime.Now);
            writer.Close();
        }
    }
}

3voto

lidqy Points 36

Je pense que vous devez faire de l'observateur un champ et ne pas le détruire prématurément. Je n'ai pas testé ce code mais vous pouvez voir les changements pertinents dans 'Watch', je pense.....

internal class Watcher : IDisposable {

    private FileSystemWatcher _watcher;
    private string _directoryPath;  
    private string _ext;

    internal Watcher (string directoryPath, string ext) {
            _directoryPath = directoryPath;
            _ext = ext;
    }
    ~Watcher () {
        Dispose();
    }
    public void Watch()
    {
        Dispose();

        _watcher = new FileSystemWatcher(_directoryPath, _ext);

        _watcher.NotifyFilter = NotifyFilters.LastAccess
                             | NotifyFilters.LastWrite
                             | NotifyFilters.FileName
                             | NotifyFilters.DirectoryName;

        _watcher.IncludeSubdirectories = true;
        // Add event handlers.
        _watcher.Changed += OnChanged;
        _watcher.Created += OnChanged;
        _watcher.Deleted += OnChanged;
        _watcher.Renamed += OnRenamed;

        // Begin watching.
        _watcher.EnableRaisingEvents = true;
    }

     public void Dispose() {
        try {
           _watcher?.Dispose();
        } catch {
           ;
        }
        _watcher = null;
     }
     //FSW event handlers...

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X