//
// Copyright (C) Tim Coleman, 2002
// (c) 2003 Ximian, Inc. (http://www.ximian.com)
-// (c) 2004 Novell, Inc. (http://www.novell.com)
+// Copyright (C) 2004, 2006 Novell, Inc (http://www.novell.com)
//
//
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
using System.ComponentModel;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Security.Permissions;
using System.Threading;
namespace System.IO {
[DefaultEvent("Changed")]
+ [IODescription ("")]
public class FileSystemWatcher : Component, ISupportInitialize {
#region Fields
throw new ArgumentException ("Empty path", "path");
if (!Directory.Exists (path))
- throw new ArgumentException ("Directory does not exists", "path");
+ throw new ArgumentException ("Directory does not exist", "path");
this.enableRaisingEvents = false;
this.filter = filter;
InitWatcher ();
}
+ [EnvironmentPermission (SecurityAction.Assert, Read="MONO_MANAGED_WATCHER")]
void InitWatcher ()
{
lock (lockobj) {
int mode = 0;
if (managed == null)
mode = InternalSupportsFSW ();
-
+
bool ok = false;
- if (mode == 3)
- ok = KeventWatcher.GetInstance (out watcher);
- else if (mode == 2)
- ok = FAMWatcher.GetInstance (out watcher);
- else if (mode == 1)
+ switch (mode) {
+ case 1: // windows
ok = DefaultWatcher.GetInstance (out watcher);
//ok = WindowsWatcher.GetInstance (out watcher);
+ break;
+ case 2: // libfam
+ ok = FAMWatcher.GetInstance (out watcher, false);
+ break;
+ case 3: // kevent
+ ok = KeventWatcher.GetInstance (out watcher);
+ break;
+ case 4: // libgamin
+ ok = FAMWatcher.GetInstance (out watcher, true);
+ break;
+ case 5: // inotify
+ ok = InotifyWatcher.GetInstance (out watcher, true);
+ break;
+ }
- if (mode == 0 || !ok)
- DefaultWatcher.GetInstance (out watcher);
+ if (mode == 0 || !ok) {
+ if (String.Compare (managed, "disabled", true) == 0)
+ NullFileWatcher.GetInstance (out watcher);
+ else
+ DefaultWatcher.GetInstance (out watcher);
+ }
+
+ ShowWatcherInfo ();
}
}
+ [Conditional ("DEBUG"), Conditional ("TRACE")]
+ void ShowWatcherInfo ()
+ {
+ Console.WriteLine ("Watcher implementation: {0}", watcher != null ? watcher.GetType ().ToString () : "<none>");
+ }
+
#endregion // Constructors
#region Properties
throw new ArgumentException ("Invalid directory name", "value", exc);
if (!exists)
- throw new ArgumentException ("Directory does not exists", "value");
+ throw new ArgumentException ("Directory does not exist", "value");
path = value;
fullpath = null;
[DefaultValue(null)]
[IODescription("The object used to marshal the event handler calls resulting from a directory change")]
+ [Browsable (false)]
public ISynchronizeInvoke SynchronizingObject {
get { return synchronizingObject; }
set { synchronizingObject = value; }
#region Methods
- [MonoTODO]
public void BeginInit ()
{
- throw new NotImplementedException ();
+ // Not necessary in Mono
}
protected override void Dispose (bool disposing)
Stop ();
}
- [MonoTODO]
public void EndInit ()
{
- throw new NotImplementedException ();
+ // Not necessary in Mono
}
- private void RaiseEvent (Delegate ev, EventArgs arg)
+ enum EventType {
+ FileSystemEvent,
+ ErrorEvent,
+ RenameEvent
+ }
+ private void RaiseEvent (Delegate ev, EventArgs arg, EventType evtype)
{
if (ev == null)
return;
- object [] args = new object [] {this, arg};
-
if (synchronizingObject == null) {
- ev.DynamicInvoke (args);
+ switch (evtype) {
+ case EventType.RenameEvent:
+ ((RenamedEventHandler)ev).BeginInvoke (this, (RenamedEventArgs) arg, null, null);
+ break;
+ case EventType.ErrorEvent:
+ ((ErrorEventHandler)ev).BeginInvoke (this, (ErrorEventArgs) arg, null, null);
+ break;
+ case EventType.FileSystemEvent:
+ ((FileSystemEventHandler)ev).BeginInvoke (this, (FileSystemEventArgs) arg, null, null);
+ break;
+ }
return;
}
- synchronizingObject.BeginInvoke (ev, args);
+ synchronizingObject.BeginInvoke (ev, new object [] {this, arg});
}
protected void OnChanged (FileSystemEventArgs e)
{
- RaiseEvent (Changed, e);
+ RaiseEvent (Changed, e, EventType.FileSystemEvent);
}
protected void OnCreated (FileSystemEventArgs e)
{
- RaiseEvent (Created, e);
+ RaiseEvent (Created, e, EventType.FileSystemEvent);
}
protected void OnDeleted (FileSystemEventArgs e)
{
- RaiseEvent (Deleted, e);
+ RaiseEvent (Deleted, e, EventType.FileSystemEvent);
}
protected void OnError (ErrorEventArgs e)
{
- RaiseEvent (Error, e);
+ RaiseEvent (Error, e, EventType.ErrorEvent);
}
protected void OnRenamed (RenamedEventArgs e)
{
- RaiseEvent (Renamed, e);
+ RaiseEvent (Renamed, e, EventType.RenameEvent);
}
public WaitForChangedResult WaitForChanged (WatcherChangeTypes changeType)
}
lastData.OldName = filename;
lastData.ChangeType = WatcherChangeTypes.Renamed;
- renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, null, filename);
+ renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, filename, "");
break;
case FileAction.RenamedNewName:
lastData.Name = filename;
lastData.ChangeType = WatcherChangeTypes.Renamed;
- if (renamed != null) {
- renamed.SetName (filename);
- } else {
- renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, filename, null);
+ if (renamed == null) {
+ renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, "", filename);
}
OnRenamed (renamed);
renamed = null;
/* 0 -> not supported */
/* 1 -> windows */
/* 2 -> FAM */
+ /* 3 -> Kevent */
+ /* 4 -> gamin */
+ /* 5 -> inotify */
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern int InternalSupportsFSW ();
-
- /*[MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern IntPtr InternalOpenDirectory (string path, IntPtr reserved);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern IntPtr InternalCloseDirectory (IntPtr handle);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern bool InternalReadDirectoryChanges (IntPtr handle,
- byte [] buffer,
- bool includeSubdirectories,
- NotifyFilters notifyFilter,
- out NativeOverlapped overlap,
- OverlappedHandler overlappedCallback);
-
- */
}
}
+