[Original] C # file monitoring-using filesystemwatcher and system. Timer. Timer,
One of my windows Services is used to communicate with other software. The method is simple file communication, that is, everyone accesses a folder and the files to be processed by the other party are put in this folder, then I monitored the folder and found that I had to take the files I needed.
Through the omnipotent baidu and Google, I found the FileSystemWatcher class to process file monitoring. Its usage is also very simple. The main code is as follows:
//Create a new FileSystemWatcher and set its properties.
watcher = new FileSystemWatcher();
watcher.Path = pathName;
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
// Only watch text files.
watcher.Filter = "*.txt";
// Add event handlers.
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Error += new ErrorEventHandler(OnError);
// Begin watching.
watcher.EnableRaisingEvents = true;
You only need to set the monitored path for the object of this class, the attributes of the monitored file, the types of monitored files, and add the event-triggered Processing Event, of course, remember to activate this object (watcher. enableRaisingEvents = true ). This class works well when monitoring local folders, but my program needs to be able to monitor network folders, that is, there is a shared folder on the network, when I use this class to monitor network folders, some problems cannot be solved,
The main problem is that when some problems occur on my network, such as I unplug the network cable and insert it back in a few minutes (it may take a few minutes. If it is too short, there will be no problem, my watcher is invalid. According to the above description on MSDN, you can add ErrorEventhandler to capture the exception event of watcher, I also found some posts on Google saying that I could capture errors and re-create watcher in error handling. However, unfortunately, my network disconnection test is always unavailable, however, it is interesting that exceptions can be caught by disabling the NIC of the local machine, but the NIC of the machine where the monitoring folder is disabled still cannot catch exceptions, so I come to the conclusion that we recommend that you use FileSystemWatcher when using local folder monitoring. It is best not to use network folder monitoring.
Since FileSystemWatcher cannot monitor network folders, how should we monitor network folders? Because the timer is used in the current service program, it is natural to think of using regular scanning of files to monitor folders. Although the method looks stupid, the effect is very good. The following is the code:
public class FolderWatchHelper
{
public string m_pathName { set; get; }
public string m_fileTypeFilter { set; get; }
public string m_logName { set; get; }
public string m_logPassword { set; get; }
public List<string> m_fileList { set; get; }
private System.Timers.Timer m_timer;
public FolderWatchHelper(float interval)
{
m_fileList = new List<string>();
m_timer = new System.Timers.Timer();
m_timer.Interval = interval;
m_timer.Elapsed += new System.Timers.ElapsedEventHandler(WatchFolder);//到达时间的时候执行事件;
m_timer.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
m_timer.Enabled = false;//是否执行System.Timers.Timer.Elapsed事件;
}
public bool IsRun()
{
return m_timer.Enabled;
}
public bool Run()
{
bool ret = true;
if (m_timer == null)
{
ret = false;
}
else if (m_timer.Enabled == false)
{
m_timer.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;
}
return ret;
}
public bool Stop()
{
bool ret = true;
if (m_timer != null && m_timer.Enabled == true)
{
m_timer.Enabled = false;
}
return ret;
}
public void WatchFolder(object source, System.Timers.ElapsedEventArgs e)
{
m_timer.Enabled = false;
bool ret = true;
if (m_pathName != "")
{
if (!Directory.Exists(m_pathName))
{
if (m_logName != "" || m_logPassword != "")
{
ConnAuthorize conn = new ConnAuthorize(m_logName, m_logPassword, m_pathName);
ret = conn.RemoteConnect(true);
}
}
if (Directory.Exists(m_pathName))
{
lock (m_fileList)
{
DirectoryInfo folder = new DirectoryInfo(m_pathName);
foreach (FileInfo file in folder.GetFiles(m_fileTypeFilter))
{
string fileName = file.FullName;
if (!m_fileList.Contains(fileName))
{
m_fileList.Add(file.FullName);
}
}
}
}
else
{
LogHelper.WriteLogFile("the watchfolder is not exist.");
}
}
m_timer.Enabled = true;
}
}
The most important thing is that the scheduled processing function has the public void WatchFolder (object source, System. timers. elapsedEventArgs e), which reads the filter-type folders in the path and puts them in the linked list, this is because some remote shared files, even if everyone is set for sharing, still use the user name and password to create a connection for the first access. The code for this function is also posted:
class ConnAuthorize
{
private string userName;
private string userPwd;
private string shareResDictionary;
// constructor
public ConnAuthorize(string myUserName, string myUserPwd, string myShareResDictionary)
{
this.userName = myUserName;
this.userPwd = myUserPwd;
this.shareResDictionary = myShareResDictionary;
}
[StructLayout(LayoutKind.Sequential)]
public struct NETRESOURCEA
{
public int dwScope;
public int dwType;
public int dwDisplayType;
public int dwUsage;
[MarshalAs(UnmanagedType.LPStr)]
public string lpLocalName;
[MarshalAs(UnmanagedType.LPStr)]
public string lpRemoteName;
[MarshalAs(UnmanagedType.LPStr)]
public string lpComment;
[MarshalAs(UnmanagedType.LPStr)]
public string lpProvider;
public override String ToString()
{
String str = "LocalName: " + lpLocalName + " RemoteName: " + lpRemoteName + " Comment: " + lpComment + " lpProvider: " + lpProvider;
return (str);
}
}
[DllImport("mpr.dll")]
public static extern int WNetAddConnection2([MarshalAs(UnmanagedType.LPArray)] NETRESOURCEA[] lpNetResource, [MarshalAs(UnmanagedType.LPStr)] string lpPassword, [MarshalAs(UnmanagedType.LPStr)] string UserName, int dwFlags);
[DllImport("mpr.dll")]
public static extern int WNetCancelConnection2(string lpName, int dwFlags, bool fForce);
[DllImport("mpr.dll")]
public static extern int WNetOpenEnum(int dwScope, int dwType, int dwUsage, [MarshalAs(UnmanagedType.LPArray)] NETRESOURCEA[] lpNetResource, ref IntPtr lphEnum);
public bool RemoteConnect(bool bConnected)
{
int res;
try
{
NETRESOURCEA[] n = new NETRESOURCEA[1];
n[0] = new NETRESOURCEA();
n[0].dwType = 1;
int dwFlags = 1; // CONNECT_INTERACTIVE;
n[0].lpLocalName = @"";
n[0].lpRemoteName = shareResDictionary;
n[0].lpProvider = null;
if (bConnected)
{
res = WNetAddConnection2(n, userPwd, userName, dwFlags);
}
else
{
res = WNetCancelConnection2(shareResDictionary, 1, true);
}
}
catch (Exception e)
{
res = 1;
LogHelper.WriteLogFile("SQLiteBackUpService ConnAuthorize:RemoteConnect exception,e info:" + e.ToString());
}
if (res == 1219)
{
res = 0;
}
return (res == 0) ? true : false;
}
}
By using the timer to monitor shared files, you can monitor local and network folders, even if the network is disconnected, as long as the network recovery program can monitor it normally.
Original C/blc recipient
What are the standards of white and paper? orz
Original Ccp
The shortest passing by of magic capital