namespace DirWatcher
{
/// <summary>
/// DirWatcher 的摘要说明。
/// </summary> /// <summary>
/// 引用表类
/// </summary>
public class RefTable
{
/// <summary>
/// 名称列表
/// </summary>
private ArrayList aNames;
/// <summary>
/// 引用数列表
/// </summary>
private ArrayList aRefs; /// <summary>
/// 构造函数
/// </summary>
public RefTable()
{
aNames = new ArrayList();
aRefs = new ArrayList();
} /// <summary>
/// 增加引用
/// </summary>
/// <param name="name">名称</param>
public void AddRef(string name)
{
lock(aNames)
{
int index = aNames.IndexOf(name);
if(index < 0) //not in table
{
aNames.Add(name);
aRefs.Add(1);
}
else
aRefs[index] = Convert.ToInt32((aRefs[index])) + 1;
}
} /// <summary>
/// 减少引用,返回引用数
/// </summary>
/// <param name="name">名称</param>
public int ReduceRef(string name)
{
int nRef = 0;
lock(aNames)
{
int index = aNames.IndexOf(name);
if(index >= 0) //in table
{
nRef = Convert.ToInt32((aRefs[index])) - 1;
aRefs[index] = nRef;
if(nRef == 0)
{//reference is null
aNames.RemoveAt(index);
aRefs.RemoveAt(index);
}
}
}
return nRef;
}
} /// <summary>
/// 文件修改事件委托
/// </summary>
[ComVisible(false)]
public delegate void DChanged(string sFilename, int nType); /// <summary>
/// 出错事件委托
/// </summary>
[ComVisible(false)]
public delegate void DError(string sError);
/// <summary>
/// DirWatcher事件接口类
/// </summary>
[GuidAttribute("7D941E16-AE9A-4311-A130-28EE2842BDA0") ]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface DirWatcherEvents
{
//event handler
void OnFileChanged(string sFilename, int nType);
void OnWatcherError(string sError);
}
/// <summary>
/// DirWatcher接口类
/// </summary>
public interface IDirWatcher
{
//methods
bool StartWatch(string sFolder);
bool StartWatch(string sFolder, string sFilter);
bool StartWatch(string sFolder, int nType);
bool StartWatch(string sFolder, string sFilter, int nType);
void StopWatch();
} [ComSourceInterfaces("DirWatcher.DirWatcherEvents")]
public class DirWatcher:IDirWatcher
{
/// <summary>
/// 文件(夹)更改事件
/// </summary>
public event DChanged OnFileChanged; /// <summary>
/// 出错事件
/// </summary>
public event DError OnWatcherError; /// <summary>
/// 监控文件夹的对象
/// </summary>
private FileSystemWatcher watcher;
/// <summary>
/// 监控类型,从右到左的位数依次表示新建、删除和更改
/// </summary>
private int type; /// <summary>
///更改延迟毫秒数
///</summary>
private int nDelay;
/// <summary>
///更改延迟列表
/// </summary>
private RefTable tDelay; /// <summary>
/// 构造函数
/// </summary>
public DirWatcher()
{
InitialMember(0);
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="delay">延迟毫秒数</param>
public DirWatcher(int delay)
{
if(delay < 0)
delay = 0;
InitialMember(delay);
}
{
/// <summary>
/// DirWatcher 的摘要说明。
/// </summary> /// <summary>
/// 引用表类
/// </summary>
public class RefTable
{
/// <summary>
/// 名称列表
/// </summary>
private ArrayList aNames;
/// <summary>
/// 引用数列表
/// </summary>
private ArrayList aRefs; /// <summary>
/// 构造函数
/// </summary>
public RefTable()
{
aNames = new ArrayList();
aRefs = new ArrayList();
} /// <summary>
/// 增加引用
/// </summary>
/// <param name="name">名称</param>
public void AddRef(string name)
{
lock(aNames)
{
int index = aNames.IndexOf(name);
if(index < 0) //not in table
{
aNames.Add(name);
aRefs.Add(1);
}
else
aRefs[index] = Convert.ToInt32((aRefs[index])) + 1;
}
} /// <summary>
/// 减少引用,返回引用数
/// </summary>
/// <param name="name">名称</param>
public int ReduceRef(string name)
{
int nRef = 0;
lock(aNames)
{
int index = aNames.IndexOf(name);
if(index >= 0) //in table
{
nRef = Convert.ToInt32((aRefs[index])) - 1;
aRefs[index] = nRef;
if(nRef == 0)
{//reference is null
aNames.RemoveAt(index);
aRefs.RemoveAt(index);
}
}
}
return nRef;
}
} /// <summary>
/// 文件修改事件委托
/// </summary>
[ComVisible(false)]
public delegate void DChanged(string sFilename, int nType); /// <summary>
/// 出错事件委托
/// </summary>
[ComVisible(false)]
public delegate void DError(string sError);
/// <summary>
/// DirWatcher事件接口类
/// </summary>
[GuidAttribute("7D941E16-AE9A-4311-A130-28EE2842BDA0") ]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface DirWatcherEvents
{
//event handler
void OnFileChanged(string sFilename, int nType);
void OnWatcherError(string sError);
}
/// <summary>
/// DirWatcher接口类
/// </summary>
public interface IDirWatcher
{
//methods
bool StartWatch(string sFolder);
bool StartWatch(string sFolder, string sFilter);
bool StartWatch(string sFolder, int nType);
bool StartWatch(string sFolder, string sFilter, int nType);
void StopWatch();
} [ComSourceInterfaces("DirWatcher.DirWatcherEvents")]
public class DirWatcher:IDirWatcher
{
/// <summary>
/// 文件(夹)更改事件
/// </summary>
public event DChanged OnFileChanged; /// <summary>
/// 出错事件
/// </summary>
public event DError OnWatcherError; /// <summary>
/// 监控文件夹的对象
/// </summary>
private FileSystemWatcher watcher;
/// <summary>
/// 监控类型,从右到左的位数依次表示新建、删除和更改
/// </summary>
private int type; /// <summary>
///更改延迟毫秒数
///</summary>
private int nDelay;
/// <summary>
///更改延迟列表
/// </summary>
private RefTable tDelay; /// <summary>
/// 构造函数
/// </summary>
public DirWatcher()
{
InitialMember(0);
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="delay">延迟毫秒数</param>
public DirWatcher(int delay)
{
if(delay < 0)
delay = 0;
InitialMember(delay);
}
/// 初始化数据成员
/// </summary>
/// <param name="delay"></param>
private void InitialMember(int delay)
{
nDelay = delay;
tDelay = new RefTable(); watcher = new FileSystemWatcher();
watcher.Changed += new FileSystemEventHandler(this.OnChanged);
watcher.Created += new FileSystemEventHandler(this.OnCreated);
watcher.Deleted += new FileSystemEventHandler(this.OnDeleted);
watcher.Error += new ErrorEventHandler(this.OnError);
}
/// <summary>
/// 开始监控
/// </summary>
/// <param name="sFolder">监控目录</param>
/// <returns>成功与否</returns>
public bool StartWatch(string sFolder)
{
return StartWatch(sFolder, "*.*", 7);
} /// <summary>
/// 开始监控
/// </summary>
/// <param name="sFolder">监控目录</param>
/// <param name="sFilter">文件过滤字符串</param>
/// <returns>成功与否</returns>
public bool StartWatch(string sFolder, string sFilter)
{
return StartWatch(sFolder, sFilter, 7);
} /// <summary>
/// 开始监控
/// </summary>
/// <param name="sFolder">监控目录</param>
/// <param name="nType">监控类型</param>
/// <returns>成功与否</returns>
public bool StartWatch(string sFolder, int nType)
{
return StartWatch(sFolder, "*.*", nType);
} /// <summary>
/// 开始监控
/// </summary>
/// <param name="sFolder">监控目录</param>
/// <param name="sFilter">文件过滤字符串</param>
/// <param name="nType">监控类型</param>
/// <returns>成功与否</returns>
public bool StartWatch(string sFolder, string sFilter, int nType)
{
type = nType; try
{
watcher.EnableRaisingEvents = false; watcher.Path = sFolder;
watcher.Filter = sFilter;
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; watcher.EnableRaisingEvents = true;
}
catch(Exception e)
{
OnWatcherError(e.Message);
return false;
}
return true;
} /// <summary>
/// 停止监控
/// </summary>
public void StopWatch()
{
watcher.EnableRaisingEvents = false;
} /// <summary>
/// 刷新监控
/// </summary>
/// <returns>与否正在监控</returns>
public bool Restart()
{
try
{
watcher.EnableRaisingEvents = false; if(Directory.Exists(watcher.Path))
watcher.EnableRaisingEvents = true;
else
return false;
}
catch(Exception e)
{
OnWatcherError(e.Message);
return false;
}
return true;
} //event handler
/// <summary>
/// 处理创建文件的事件
/// </summary>
/// <param name="source">错误参数</param>
private void OnError(object source, ErrorEventArgs e)
{
if(typeof(System.IO.InternalBufferOverflowException).Equals(e))
{
// Specify what is done when the buffer is overflow
try
{
watcher.EnableRaisingEvents = false; if(watcher.InternalBufferSize < 0x8000)
watcher.InternalBufferSize = watcher.InternalBufferSize << 1; //增大缓冲区
else
watcher.InternalBufferSize = 0x4000; watcher.EnableRaisingEvents = true;
}
catch(Exception ex)
{
OnWatcherError(ex.Message);
}
}
else
{
try
{
watcher.EnableRaisingEvents = true; //try to recover
}
catch(Exception ex)
{
OnWatcherError(ex.Message);
}
}
} //event handler
/// <summary>
/// 处理创建文件的事件
/// </summary>
/// <param name="source">引发创建事件的源</param>
/// <param name="e">创建文件事件的参数</param>
private void OnCreated(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is created
if((type & 1) != 0)
OnFileChanged(e.FullPath, 1); if((type & 4) != 0)
{
tDelay.AddRef(e.FullPath); SendChangedThread s = new SendChangedThread(tDelay, e.FullPath, 1000, OnFileChanged);
try
{
new Thread (new ThreadStart(s.Send)).Start();
}
catch
{//can't open new thread
if(tDelay.ReduceRef(e.FullPath) <= 0)
OnFileChanged(e.FullPath, 4);
}
}
} /// <summary>
/// 处理删除文件的事件
/// </summary>
/// <param name="source">引发删除事件的源</param>
/// <param name="e">删除文件事件的参数</param>
private void OnDeleted(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is deleted.
if((type & 2) != 0)
OnFileChanged(e.FullPath, 2);
} /// <summary>
/// 处理更改文件的事件
/// </summary>
/// <param name="source">引发更改事件的源</param>
/// <param name="e">更改文件事件的参数</param>
private void OnChanged(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed
if((type & 4) != 0)
{
tDelay.AddRef(e.FullPath); SendChangedThread s = new SendChangedThread(tDelay, e.FullPath, 1000, OnFileChanged);
try
{
new Thread (new ThreadStart(s.Send)).Start();
}
catch
{//can't open new thread
if(tDelay.ReduceRef(e.FullPath) <= 0)
OnFileChanged(e.FullPath, 4);
}
}
} } /// <summary>
/// 产生文件更改事件,由调用者用多线程方式运行
/// </summary>
class SendChangedThread
{
private RefTable table;
private string fullName;
private int sleepTime;
private DChanged dlg; /// <summary>
/// 构造函数
/// </summary>
/// <param name="t">引用表</param>
/// <param name="name">引用名</param>
/// <param name="time">线程挂起时间</param>
/// <param name="d">发出的事件</param>
public SendChangedThread(RefTable t, string name, int time, DChanged d)
{
table = t;
fullName = name;
sleepTime = time;
dlg = d;
} /// <summary>
/// 发送事件
/// </summary>
public void Send()
{
Thread.Sleep(sleepTime);
if(table.ReduceRef(fullName) <= 0)
dlg(fullName, 4);
}
}
}