public SmartWatcherService()
        {
            InitializeComponent();


            #if DEBUG
            //Launches and attaches a debugger to the process. Remove it for production
            System.Diagnostics.Debugger.Launch();
            ServiceLogger.LogDebug("Start Debugging.");
            #endif


            // intilaize files processor to maintains files queue
            processor = new FileProcessor();

            LoadPlugIns();
            RegisterWatchers();


            _smartTimer = new SmartTimer(_interval);
            _smartTimer.EventSmartTimerTick += smartTimer_EventSmartTimerTick;
            if (_enableTimer)
            {
                ServiceLogger.LogInfo("Start: SmartTimer");
                _smartTimer.StartTimer();
            }
        }
        private void RegisterWatchers()
        {
            ServiceLogger.LogInfo("RegisterWatchers() - Start");
            foreach (IPlugin plugin in lstPlugins)
            {
                // Create Watching Directory if not exist
                if (!Directory.Exists(plugin.WatchPath))
                {
                    ServiceLogger.LogInfo("Directory not exist, creating watching directory, directory name: " + plugin.WatchPath);
                    Directory.CreateDirectory(plugin.WatchPath);
                }

                try
                {
                    FileSystemWatcher watcher = new FileSystemWatcher();
                    watcher.Path                = plugin.WatchPath;
                    watcher.Filter              = plugin.Filter;
                    watcher.NotifyFilter        = plugin.NotifyFilter;
                    watcher.Changed            += fswWatcher_Changed;
                    watcher.Created            += fswWatcher_Created;
                    watcher.Deleted            += fswWatcher_Deleted;
                    watcher.Renamed            += fswWatcher_Renamed;
                    watcher.EnableRaisingEvents = true;
                    _lstWatchers.Add(watcher);
                    ServiceLogger.LogInfo("Watcher added, plugin name: " + plugin.Name);
                }
                catch (Exception ex)
                {
                    ServiceLogger.LogInfo("RegisterWatchers() - Error: " + ex.Message);
                }

                ServiceLogger.LogInfo("RegisterWatchers() - Finish");
            }
        }
        private void ProcessFile(string fileInfo)
        {
            ServiceLogger.LogInfo("ProcessFile() - Start");
            string[] file = fileInfo.Split('|');
            WatcherChangeTypes changeType;
            WatcherChangeTypes.TryParse(file[0], true, out changeType);
            string filepath = file[1];

            if (!File.Exists(filepath))
            {
                ServiceLogger.LogInfo("File is not exist, File name: " + filepath);
                return;
            }

            // Check if file is accessble
            if (!WaitReady(filepath, SmartWatcherService.SettingsReadTries))
            {
                ServiceLogger.LogInfo("File can be opened with write permission, File name: " + filepath);
                return;
            }

            foreach (IPlugin plugin in SmartWatcherService.lstPlugins)
            {
                string strFiletr = plugin.Filter.Replace("*", @"\\*");
                Match match = Regex.Match(Path.GetFileName(filepath), strFiletr);
                if (match.Success == true)
                {
                    Func<string, bool> pluginFunc = null;
                    switch (changeType)
                    {
                            case WatcherChangeTypes.Created:
                            {
                                pluginFunc = plugin.FileCreated;
                                break;
                            }
                            case WatcherChangeTypes.Changed:
                            {
                                pluginFunc = plugin.FileChanged;
                                break;
                            }
                            case WatcherChangeTypes.Renamed:
                            {
                                pluginFunc = plugin.FileRenamed;
                                break;
                            }
                            case WatcherChangeTypes.Deleted:
                            {
                                pluginFunc = plugin.FileDeleted;
                                break;
                            }
                    }
                    ServiceLogger.LogInfo("ProcessPluginAction, Plugin Name: " + plugin.Name);
                    ProcessPluginAction(pluginFunc, filepath, plugin.ArchiveFiles, plugin.DeleteFiles, plugin.FilePrefix,
                                        plugin.ZipPassword);
                }
            }
            ServiceLogger.LogInfo("ProcessFile() - Finish");
        }
 protected override void OnStop()
 {
     ServiceLogger.LogInfo("SmartWatcher service stopping.");
     if (_smartTimer != null)
     {
         _smartTimer.StopTimer();
         _smartTimer = null;
     }
 }
        public bool Register(IPlugin plugin)
        {
            ServiceLogger.LogInfo("Register(IPlugin plugin) - Start");
            ServiceLogger.LogInfo("plugin name:" + plugin.Name);


            ServiceLogger.LogInfo("Register(IPlugin plugin) - Finish");
            return(true);
        }
        private void LoadPlugIns()
        {
            ServiceLogger.LogInfo("LoadPlugIns() - Start");
            if (!Directory.Exists(_PluginFolder))
            {
                ServiceLogger.LogInfo("Directory not exist, creating directory, directory name: " + _PluginFolder);
                Directory.CreateDirectory(_PluginFolder);
            }


            string[] pluginFiles = Directory.GetFiles(_PluginFolder, "*.plug");
            foreach (string pluginFile in pluginFiles)
            {
                try
                {
                    Assembly assembly = Assembly.LoadFrom(pluginFile);

                    System.Type[] assemblyTypes = assembly.GetTypes();
                    foreach (System.Type type in assemblyTypes)
                    {
                        if (type.GetInterface("IPlugin") != null)
                        {
                            if (type.GetCustomAttributes(typeof(PlugDisplayNameAttribute),
                                                         false).Length != 1)
                            {
                                throw new PlugNotValidException(type,
                                                                "PlugDisplayNameAttribute is not supported");
                            }
                            if (type.GetCustomAttributes(typeof(PlugDescriptionAttribute),
                                                         false).Length != 1)
                            {
                                throw new PlugNotValidException(type,
                                                                "PlugDescriptionAttribute is not supported");
                            }
                            IPlugin plugin = (IPlugin)Activator.CreateInstance(type, new object[] {});
                            plugin.Host = this;
                            ServiceLogger.LogInfo("Add plugin, plugin name:" + plugin.Name);
                            lstPlugins.Add(plugin);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ServiceLogger.LogError("LoadPlugIns() - Error: " + ex.Message);
                }
            }
            ServiceLogger.LogInfo("LoadPlugIns() - Finish");
        }
        private void ProcessPluginAction(Func<string, bool> pluginMethod, string fileFullName, bool archiveFiles, bool deleteFiles, string filePrefix, string zipPassword)
        {
            ServiceLogger.LogInfo("ProcessPluginAction() - Start");
            string strArchivePath = SmartWatcherService.SettingsFailureArchivePath;
            try
            {
                pluginMethod(fileFullName);
                strArchivePath = SmartWatcherService.SettingsSuccessArchivePath;

            }
            catch (Exception ex)
            {
                //ToDo: add exception handeling
                ServiceLogger.LogError("() - Error: " + ex.Message);
            }
            finally
            {
                if (archiveFiles == true)
                {
                    string strArchiveFileName = filePrefix + "_" + DateTime.Now.ToString("yyyyMMddHHmmssss") + "_" +
                                                Path.GetFileName(fileFullName) + "." + SmartWatcherService.SettingsZipFileExtention;
                    ZipUtil.ZipFile(fileFullName, strArchivePath + strArchiveFileName, zipPassword);
                }
                if (deleteFiles == true)
                {
                    if (File.Exists(fileFullName))
                    {
                        // Check if file is accessble
                        if (FileProcessor.WaitReady(fileFullName, SmartWatcherService.SettingsReadTries) == true)
                        {
                            try
                            {
                                File.Delete(fileFullName);
                            }
                            catch (Exception ex)
                            {
                                //ToDo: add exception handeling
                                ServiceLogger.LogError("ProcessPluginAction() - Failed to delete file, file name: " + fileFullName + " Error Message: " + ex.Message);
                            }

                        }
                    }
                }
            }

            ServiceLogger.LogInfo("ProcessPluginAction() - Finish");
        }
 protected override void OnStart(string[] args)
 {
     ServiceLogger.LogInfo("SmartWatcher service starting.");
     try
     {
         // Create Failure Archiving Directory
         if (!Directory.Exists(SettingsFailureArchivePath))
         {
             Directory.CreateDirectory(SettingsFailureArchivePath);
         }
         // Create Success Archiving Directory
         if (!Directory.Exists(SettingsSuccessArchivePath))
         {
             Directory.CreateDirectory(SettingsSuccessArchivePath);
         }
     }
     catch (Exception ex)
     {
         ServiceLogger.LogError(ex.Message + "/n" + ex.StackTrace);
         throw;
     }
 }
 /// <summary>
 /// Waits until a file can be opened with write permission
 /// </summary>
 private static bool WaitReady(string fileName, int numberOfTries)
 {
     // file not ready
     bool result = false;
     int intCounter = 0;
     while (intCounter <= numberOfTries)
     {
         try
         {
             using (Stream stream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
             {
                 if (stream != null)
                 {
                     Trace.WriteLine(String.Format("Output file {0} ready.", fileName));
                     // file is ready
                     result = true;
                     break;
                 }
             }
         }
         catch (FileNotFoundException ex)
         {
             ServiceLogger.LogError("WaitReady - Error:" + String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
         }
         catch (IOException ex)
         {
             ServiceLogger.LogError("WaitReady - Error:" + String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
         }
         catch (UnauthorizedAccessException ex)
         {
             ServiceLogger.LogError("WaitReady - Error:" + String.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
         }
         Thread.Sleep(500);
         intCounter += 1;
     }
     return result;
 }
 /// <summary>
 /// Event occurs when the a File or Directory is renamed
 /// </summary>
 private void fswWatcher_Renamed(object sender,
                                 System.IO.RenamedEventArgs e)
 {
     ServiceLogger.LogInfo("Event: File Renamed, File Name: " + e.FullPath + " , Change Type: " + e.ChangeType);
     processor.QueueInput(e.FullPath, e.ChangeType);
 }