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);
}

解决方案 »

  1.   

    /// <summary>
    /// 初始化数据成员
    /// </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);
    }
    }
    }