Here is my final code for the FileSystemWatcher class. I added two things. One, I noted in my last post. I also updated the code to make a change to the properties of the file I am overwriting on the target servers. I found that if the file was read-only on the target server, it raised an error and did not overwrite the file.
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.IO;
using System.Xml;
namespace Replicator
{
public class FileReplicator : System.ServiceProcess.ServiceBase
{
private FileSystemWatcher FileWatcher;
private XmlDocument Config;
private System.Collections.Hashtable TargetServers;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
public FileReplicator()
{
// This call is required by the Windows.Forms Component Designer.
InitializeComponent();
}
// The main entry point for the process
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;
// More than one user Service may run within the same process. To add
// another service to this process, change the following line to
// create a second service object. For example,
//
// ServicesToRun = New System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
//
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new FileReplicator() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.FileWatcher = new System.IO.FileSystemWatcher();
((System.ComponentModel.ISupportInitialize)(this.FileWatcher)).BeginInit();
//
// FileWatcher
//
this.FileWatcher.EnableRaisingEvents = true;
this.FileWatcher.Changed += new System.IO.FileSystemEventHandler(this.FileWatcher_Changed);
this.FileWatcher.Created += new System.IO.FileSystemEventHandler(this.FileWatcher_Changed);
//Allow Pause and Continue actions on the service
this.CanPauseAndContinue = true;
//Allow people to shutdown the service
this.CanShutdown = true;
//The name that will show in the services control panel
this.ServiceName = "Production Image Replicator";
((System.ComponentModel.ISupportInitialize)(this.FileWatcher)).EndInit();
this.EventLog.WriteEntry("Production Image Replicator Service Initializing.",System.Diagnostics.EventLogEntryType.Information,1,1);
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
this.EventLog.WriteEntry("Production Image Replicator Service Dispose.",System.Diagnostics.EventLogEntryType.Information,1,1);
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
///
/// Set things in motion so your service can do its work.
///
protected override void OnStart(string[] args)
{
this.EventLog.WriteEntry("Starting Production Image Replicator Service.",System.Diagnostics.EventLogEntryType.Information,1,1);
this.FileWatcher.EnableRaisingEvents = true;
Config = new XmlDocument();
TargetServers = new Hashtable();
string localpath = System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
try
{
Config.Load(localpath+"\\config.xml");
this.EventLog.WriteEntry("Loaded Config File at "+localpath+"\\config.xml",System.Diagnostics.EventLogEntryType.Information,1,1);
}
catch (System.Xml.XmlException xex)
{
this.EventLog.WriteEntry("Could not open config file. Error was:\n"+xex.Message,System.Diagnostics.EventLogEntryType.Error,1,1);
}
FileWatcher.Path = Config.SelectSingleNode("configuration/sourceserver/@path").Value;
foreach (XmlNode node in Config.SelectNodes("configuration/targetserver"))
{
TargetServers.Add(node.SelectSingleNode("@name").Value,node.SelectSingleNode("@path").Value);
}
FileWatcher.Filter = "*.gif";
FileWatcher.NotifyFilter=NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size;
FileWatcher.IncludeSubdirectories=false;
FileWatcher.InternalBufferSize=40960;
this.EventLog.WriteEntry("Production Image Replicator Service Started.",System.Diagnostics.EventLogEntryType.Information,1,1);
}
///
/// Pause this service.
///
protected override void OnPause()
{
this.FileWatcher.EnableRaisingEvents = false;
this.EventLog.WriteEntry("Production Image Replicator Service Paused.",System.Diagnostics.EventLogEntryType.Information,1,1);
}
///
/// Stop this service.
///
protected override void OnStop()
{
this.FileWatcher.EnableRaisingEvents = false;
this.EventLog.WriteEntry("Production Image Replicator Service Stopped.",System.Diagnostics.EventLogEntryType.Information,1,1);
}
private void FileWatcher_Changed(object sender, System.IO.FileSystemEventArgs e)
{
this.EventLog.WriteEntry("In FileWatcher_Changed.",System.Diagnostics.EventLogEntryType.Information,1,1);
IDictionaryEnumerator ListEnumerator = TargetServers.GetEnumerator();
string strCopyToPath = "";
try
{
if (e.ChangeType==WatcherChangeTypes.Created || e.ChangeType==WatcherChangeTypes.Changed)
{
while (true)
{
//don't do anything till the file has finished copying to the source server
try
{
if (File.Exists(e.FullPath))
break;
}
catch(IOException ix)
{
//ignore the exception, continue trying to open file
}
}
this.EventLog.WriteEntry("Create Event Triggered: "+e.FullPath,System.Diagnostics.EventLogEntryType.Information,1,1);
while (ListEnumerator.MoveNext())
{
strCopyToPath = ListEnumerator.Value.ToString()+"\\"+e.Name;
try
{
if (File.Exists(strCopyToPath))
{
File.SetAttributes(strCopyToPath,FileAttributes.Normal);
}
File.Copy(e.FullPath, strCopyToPath, true);
this.EventLog.WriteEntry("Copied File to "+strCopyToPath,System.Diagnostics.EventLogEntryType.Information,1,1);
}
catch(IOException ix)
{
this.EventLog.WriteEntry("IOException while copying to " + strCopyToPath + ". Error was:\n"+ix.Message,System.Diagnostics.EventLogEntryType.Error,1,1);
}
}
}
}
catch (IOException ix)
{
this.EventLog.WriteEntry("IOException while copying files. Error was:\n"+ix.Message,System.Diagnostics.EventLogEntryType.Error,1,1);
}
catch (Exception x)
{
this.EventLog.WriteEntry("Unknown Exception while copying files. Error was:\n"+x.Message,System.Diagnostics.EventLogEntryType.Error,1,1);
}
}
}
}