问题
I've written a Windows Service (using Visual Studio 2010 Premium, C#, .NET 4) to monitor a folder. All it does is detect when a change is made in the folder (a file/folder added, something deleted, etc) and writes the detections to a text file. Not an Event Log, just a normal .txt file.
Now, it installs fine (I presume), and it shows up in Computer Management and allows me to run it. It supposed to write "Monitoring started" to the file - but it doesn't. Then, when I try to stop the service it gives me this error:
"Windows could not stop the FileMonitoring service on Local Computer. The service did not return an error. This could be an internal Windows error or an internal service error. If the problem persists, contact your system administrator."
And doesn't stop. Then, when I attempt to stop it again, I get this error:
"Windows could not stop the FileMonitoring service on Local Computer. Error 1061: The service cannot accept control messages at this time."
And then it stops.
Does anyone have any idea how to resolve this issue? Before this service, I just made a simple service that wrote to a .txt file "Started" when the service started and "Stopped" when the service stopped, and it worked perfectly. All that's added into this is the used of FileSystemWatcher
.
Any help would be much appreciated, and I'll give any info/code snippets you need, just ask.
Thanks in advance!
EDIT:
Here's some code for you:
protected override void OnStart(string[] args)
{
watcher = new FileSystemWatcher();
watcher.Path = @"C:\temp\services\Watched";
watcher.Changed += new FileSystemEventHandler(LogFileSystemChanges);
watcher.Created += new FileSystemEventHandler(LogFileSystemChanges);
watcher.Deleted += new FileSystemEventHandler(LogFileSystemChanges);
watcher.Renamed += new RenamedEventHandler(LogFileSystemRenaming);
watcher.Error += new ErrorEventHandler(LogBufferError);
watcher.EnableRaisingEvents = true;
LogEntry("Monitoring Started.");
}
protected override void OnStop()
{
watcher.EnableRaisingEvents = false;
watcher.Dispose();
LogEntry("Monitoring Stopped.");
}
void LogEntry(string message)
{
counter++;
FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(counter + ". " + message);
fs.Close();
sw.Close();
}
EDIT 2:
Okay, someone noted the fact I had not closed my Streams. Silly, silly me. Now, I ran the service after that, and didn't get the same error, I got this one:
"The FileMonitoring service on Local Computer started and then stopped. Some services stop automatically is they are not in use by other services or programs."
This seems a lot simpler but I'm still at a loss. Any ideas?
Thanks so much!
回答1:
One thing you will have to consider (although I don't think it's a problem in your case) is concurrent access to the file.
To ensure that streams are closed it is good practice to wrap them in using statements as well.
protected override void OnStart(string[] args)
{
watcher = new FileSystemWatcher();
watcher.Path = @"C:\temp\services\Watched";
watcher.Changed += new FileSystemEventHandler(LogFileSystemChanges);
watcher.Created += new FileSystemEventHandler(LogFileSystemChanges);
watcher.Deleted += new FileSystemEventHandler(LogFileSystemChanges);
watcher.Renamed += new RenamedEventHandler(LogFileSystemRenaming);
watcher.Error += new ErrorEventHandler(LogBufferError);
watcher.EnableRaisingEvents = true;
LogEntry("Monitoring Started.");
}
protected override void OnStop()
{
watcher.EnableRaisingEvents = false;
watcher.Dispose();
LogEntry("Monitoring Stopped.");
}
private object lockObject = new Object();
void LogEntry(string message)
{
lock (lockObject)
{
counter++;
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(counter + ". " + message);
}
}
}
Another trick you can use is the System.Diagnostics.Debugger.Break(); method. If you put this in the beginning of your service it should prompt you to attach Visual Studio to it and you can step through it.
Hope that helps.
回答2:
maybe the logfile is still blocked from the previous processes. try to delete it. if it is possible, then this is not the case.
if it's not possible to delete the file, try a reboot and try to delete it again. should work now.
in future the file will no longer be blocked, because you closed the stream. but you should implement a try-catch-finally so that the fileaccess is definetly closed after the error.
回答3:
This line:
sw.Close();
is probably throwing an ObjectDisposedException because you have already closed its underlying file stream while it still had data to flush to it.
The uncaught exception will crash the process, and the error you see is the Windows SCM reporting that it noticed this.
EDIT: Also, I think you probably need to seek to the end of the file before writing the entry. This may be why you aren't seeing the Start event messages.
来源:https://stackoverflow.com/questions/4885080/c-sharp-windows-service-not-running-correctly