Reputation: 105
So, I have created a windows service, where I use a FileSystemWatcher
to watch different directories. Every time changed files are detected I copy them in a different directory, so I can work with them later.
This works perfectly when I run the program as a Console Application.
When I run it as a service, I can start and stop the service properly, but it won't detect any kind of event. I have tried to debug my service and I found out that the error is coming from the fact that I don't stop the FileSystemWatcher
.
For my console App, I have this code for the Watch()
method:
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') ;
}
}
So, I stop the program if the user presses 'q'.
For my Windows Service, I have this code for the Watch()
method:
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;
}
}
So, here I don't stop the FileSystemWatcher
at all, because as I don't have a direct interaction with the user, I don't know how to stop it. Can you please help me to find a solution to this?
These are the OnStart()
and OnStop()
methods:
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();
}
}
}
Upvotes: 2
Views: 5380
Reputation: 2453
I think you need to make the watcher a field and not to dispose it prematurely. I didn't test this code but you see the relevant changes in 'Watch', i think....
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...
}
Upvotes: 3