Update 2008-07-03 - Vista Fix
If you are having trouble accessing the folder with permissions, you could always force UAC to elevate your securitygrade.
Use:
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
It's under System.Security.Permissions
namespace.
Introduction
I'm currently working on a project that needed to watch a folder's activity and trigger event in my application. So I started to search The Code Project and found out that the only code that existed was from 2003, and it did not even work (maybe because I'm on Vista?). Either ways, there were threads crossing other threads and fuzzy commenting, so I decided to clean it up. It's originally based on Jayesh Jaine's work who did this in VB.NET back in 2002. Then in 2003 Gerald Nelson picked it up, translated it to C#, but somehow he did not finish it. It was not threadsafe, blah blah blah...
Alright, let's continue.
Using the Code
It's really easy to use and I commented it well. As you can see below, we first declare _watchFolder
as a FileSystemWatcher
from the System.IO
.
We just set the parameters to what we want to listen to and then connect the eventhandlers to some function.
FileSystemWatcher _watchFolder = new FileSystemWatcher();
private void startActivityMonitoring(string sPath)
{
_watchFolder.Path = sPath;
_watchFolder.NotifyFilter = System.IO.NotifyFilters.DirectoryName;
_watchFolder.NotifyFilter =
_watchFolder.NotifyFilter | System.IO.NotifyFilters.FileName;
_watchFolder.NotifyFilter =
_watchFolder.NotifyFilter | System.IO.NotifyFilters.Attributes;
_watchFolder.Changed += new FileSystemEventHandler(eventRaised);
_watchFolder.Created += new FileSystemEventHandler(eventRaised);
_watchFolder.Deleted += new FileSystemEventHandler(eventRaised);
_watchFolder.Renamed += new System.IO.RenamedEventHandler(eventRenameRaised);
try
{
_watchFolder.EnableRaisingEvents = true;
}
catch (ArgumentException)
{
abortAcitivityMonitoring();
}
}
Just a quick look at the function that handles the events.
private void eventRaised(object sender, System.IO.FileSystemEventArgs e)
{
switch (e.ChangeType)
{
case WatcherChangeTypes.Changed:
TS_AddLogText(string.Format("File {0} has been modified\r\n", e.FullPath));
break;
case WatcherChangeTypes.Created:
TS_AddLogText(string.Format("File {0} has been created\r\n", e.FullPath));
break;
case WatcherChangeTypes.Deleted:
TS_AddLogText(string.Format("File {0} has been deleted\r\n", e.FullPath));
break;
default:
break;
}
}
Points of Interest
One thing that I discovered while doing this is that when creating a file in the folder you are monitoring, windows is modifying this file twice.
Another thing is when an event is raised, the event is called from another thread. Now this causes it to crash if we don't make any control or component we want to access that was created on other threads to threadsafe. There is an example in the source code on how to do this.
Tip: Don't forget to set...
_watchFolder.EnableRaisingEvents = false;
... when you want it to stop listening. If you assign the listeners twice, it will trigger both events. Happy coding, my friends!
History
- 21st April, 2008: First release
- 3rd July, 2008: Vista fix