Multiple instances of FileSystemWatcher ??????

D

David

I have been working on trying to write a directory watcher service.
One of the requirments is that it be able to watch multiple
directories, not sub directories of one parent directory, but just
multiple directories.

I have hit a snag and don't know how to get around it.

Basically I read in a list of directories from the app.config and stuff
them into an array, so that I have something like this:
sDirsToWatch[0] = "C:\Temp"
sDirsToWatch[1] = "D:\Temp"

Then I do the following

For (i = 0; i < sDirsToWatch.Length; i++)
{
FileSystemWatcher myWatcher = new System.IO.FileSystemWatcher();
myWatcher.NotifyFilter = NotifyFilters.DirectoryName |
NotifyFilters.FileName | NotifyFilters.Attributes;
myWatcher.Deleted += new FileSystemEventHandler(LogDeleted);
myWatcher.Path = sDirsToWatch;
myWatcher.EnableRaisingEvents = true;
}

Now when it gets to either the .Path line or to when it gets to the
..EnableRaisingEvents for the 2nd directory, I get an error: Error
reading the D:\Temp directory

I think what is happening is that all of the objects that I am creating
are named the same, so its causing problems.

So my question is, how do I dynamically name my FileSystemWatcher
object ?

Any help would be most appreciated.

Thanks

David
 
N

Nicholas Paldino [.NET/C# MVP]

David,

It doesn't look like this is the case. Are you running this in a
service? Are you sure that you have access to the drive itself (if it is a
service, then it might not, by default). Also, are you sure that the
directory itself exists?

Hope this helps.
 
D

David

Nicholas:

Not running this as a service yet, until I get the code nailed down I
am doing it from a Windows Form application, but it will be moved to a
service once I get the code working.

Both directories exist on my local hard drive and I can freely copy and
delete files from them.

Thanks for the help

David
 
A

Andy

David,

I don't think you can have one watcher watching multiple directories.
Try creating a new instance for each directory you would like to watch.

I think the problem is that everytime you hit the top of your loop, you
make myWatcher point to a new object, and the old one gets destoryed
since nothing is referencing it any longer.

Andy
 
N

Nicholas Paldino [.NET/C# MVP]

David,

The naming of the file system watchers is not an issue, since you create
a new one each time you iterate through the loop. Are there any more
details to the exception?

If you want to hold all the instances, you can create an array of file
system watchers, and populate each element of the array with a reference to
a different instance.
 
D

David

Andy:

I agree with what you are saying, I'm pretty sure that is what the
problem is.

What I don't know how to do is dynamically name the FileSystemWatcher.
Since I am using a for statement, I was hoping I could somehow derive
the name of the object every time the loop iterates, so for example
since there are only 2 directories in the array, I would end up with
FileSystemWatcher objects named: myWatcher0, myWatcher1.

But if I try and build a string for the FileSystemWatcher object name
and then reference that variable on the line where I say
FileSystemWatcher myWatcher = new System.IO.FileSystemWatcher();, I get
an error during compile time.

So I guess that the question is given this line of code:
FileSystemWatcher myWatcher = new System.IO.FileSystemWatcher();

How do I dynamically name the object myWatcher so that when it iterates
through the for, its not always the same name ?
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

I would change a little your code:

ArrayList watchers = new ArrayList();

For (i = 0; i < sDirsToWatch.Length; i++)
{
FileSystemWatcher myWatcher = new System.IO.FileSystemWatcher();
myWatcher.NotifyFilter = NotifyFilters.DirectoryName |
NotifyFilters.FileName | NotifyFilters.Attributes;
myWatcher.Deleted += new FileSystemEventHandler(LogDeleted);
myWatcher.Path = sDirsToWatch;
myWatcher.
myWatcher.EnableRaisingEvents = true;
watchers.Add( myWatcher);
}

Try it, basically I'm keeping the references to them. ( in case you need to
disable one afterwards )

Also, and here is where your error may be, rewrite it like this:

sDirsToWatch[0] = @"C:\Temp";
sDirsToWatch[1] = @"D:\Temp";

cheers;
 
A

Andy

Dave,

I think what you're saying you want is to name the object using the
value stored in a string.

Something like:
string nameIt = "watcher01";

FileSystemWatcher nameIt = new ...

If thats what you want, you can't really do that..however you could
store your watcher objects in a HashTable.

HashTable watchers = new HashTable();
FileSystemWatcher watcher;

for( int i = 0 ; i < 2 ; i += 1 0 {
watcher = new FileSystemWatcher();
// set its properties
watchers.Add( "watcher" + i.ToSring(), watcher );
}

Then access them like so
watcher = (FileSystemWatcher)watchers[ "watcher1" ];

Andy
 
D

David

Ignacio:

Thanks for the reply, I did try that originally, but that doesn't seem
to work either, basically on the 2nd interation into the loop when it
gets to the line for myWatcher.EnableRaisingEvents = true; it throws an
error.

Here is the code exactly:

int i;
string sAppRead = @"C:\FileWatcherTest2, C:\FileWatcherTest";

string [] sDirsToWatch;

sDirsToWatch = sAppRead.Split(',');

ArrayList FileWatchers = new ArrayList();

for (i = 0; i < sDirsToWatch.Length; i++)
{
FileSystemWatcher myWatcher = new System.IO.FileSystemWatcher();
myWatcher.NotifyFilter = NotifyFilters.DirectoryName |
NotifyFilters.FileName | NotifyFilters.Attributes;
myWatcher.Deleted += new FileSystemEventHandler(LogDeleted);
myWatcher.Path = sDirsToWatch;
myWatcher.EnableRaisingEvents = true;

FileWatchers.Add(myWatcher);
}
 
D

David

Nicholas:

Are you sure the naming of the file system watcher is not an issue ?
It would seem to me now that I have the creation code in a loop, that
everytime the loop iterates a object gets created, but it has the same
name as the one that just got created, so doesn't that mangle the first
one ?

For instance: I create a object called myWatcher, set all of its
properties and enable it to start watching, then the loop starts over
and I create a new object called myWatcher, what has happened to the
first on that was created ?

Here is the exact message from the development environment when it hits
the line myWatcher.EnableRaisingEvents = true;

An unhandled exception of type 'System.IO.FileNotFoundException'
occurred in system.dll

Additional information: Error reading the C:\FileWatcherTest
directory.
From this text, I would think that the directory doesn't exist, but I
know it does. I just created it.

Thanks

David
 
D

David

Andy:

Yep, that is what I was wanting to do, If I manually create two objects
with code and name them completely different, then this works fine, so
what you are describing with the nameIt string is what I was wanting.

I tried your Hashtable example, I end up with the same error.

Heres what I tried:

int i;
string sAppRead = @"C:\FileWatcherTest, C:\FileWatcherTest";
string[] sDirsToWatch;

sDirsToWatch = sAppRead.Split(',');

Hashtable watchers = new Hashtable();
FileSystemWatcher watcher;
FileSystemWatcher watcher1;

for (i = 0; i < sDirsToWatch.Length; i++)
{
watcher = new FileSystemWatcher();
watcher.NotifyFilter = NotifyFilters.DirectoryName |
NotifyFilters.FileName | NotifyFilters.Attributes;
watcher.Deleted += new FileSystemEventHandler(LogDeleted);
watcher.Path = sDirsToWatch;

watchers.Add("watcher" + i.ToString(), watcher);
}

watcher = (FileSystemWatcher)watchers["watcher0"];
watcher.EnableRaisingEvents = true;

watcher1 = (FileSystemWatcher)watchers["watcher1"];
watcher1.EnableRaisingEvents = true;
 
G

Guest

string sAppRead = @"C:\FileWatcherTest2, C:\FileWatcherTest";

The problem lies in that it cannot find the folder named "
c:\FileWatcherTest": note the space.

Either use
string sAppRead = @"C:\FileWatcherTest2,C:\FileWatcherTest";
without a space after the comma or trim the folderstring.

myWatcher.Path = sDirsToWatch.Trim();
 
A

Andy

Hey David,

If you're only getting the error on the second watcher, I suspect its
because of the space after the comma in your path list. Try removing
the space, maybe the watcher class doesn't like having it as the first
character in the path to watch.

andy
 
D

David

Andy:

You are correct, I was totally missing the space in front of the second
string.

So actually the directory didn't exist.

Thanks for the help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top