Link to home
Start Free TrialLog in
Avatar of mmunger
mmungerFlag for United States of America

asked on

C# Service FileSystemwatcher isse

I had this question after viewing Windows Service- File Watcher.

I am working on an application that monitors a folder and triggers a procedure to parse a file when a new file is saved to the folder.  My current application works for only one file and then it does not fire the procedure again.  I need it to fire the changed event everytime a new file is saved to that folder.  My service continues to run and it doesn't log anything so it doesn't seem to be catching errors.  Attached is the source code for my service. Any help would be appreciated.  

Thanks,

@CreativeTechie
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

You haven't attached the code
Avatar of mmunger

ASKER

My bad
  public partial class IKONEDD : ServiceBase
    {
        public FileSystemWatcher watcher;
        
        //Constants used in IKONEDD service
        #region Constants
        public const string MyServiceName = "IKONEDDSERV";
         
        //private FileSystemWatcher watcher;
        //X3 destination of pdf on X3 application Server
        private static string TempDirectory = ConfigurationManager.AppSettings.Get("TempDirectory");
        //directory used to parse pdf document
        private static string ParseDir = ConfigurationManager.AppSettings.Get("ParseDirectory");
        //email address where diagnostic report is sent
        private static string diagEmail = ConfigurationManager.AppSettings.Get("Diagnostic Email");
        //X3 Folder that the solution is pulling from
        private static string X3Folder = ConfigurationManager.AppSettings.Get("X3Folder");
        //email address set for emails sent
        private static string documentEmailFrom = ConfigurationManager.AppSettings.Get("Email From");
        
        #endregion
        public IKONEDD()
        {
            InitializeComponent();
           
        }
        //Actions associated with IKONEDD service
        #region Service Methods
        //Runs when service starts
        protected override void OnStart(string[] args)
        {
            try
            {
                
                Directory.CreateDirectory(ParseDir);
                Directory.CreateDirectory(TempDirectory);
                watcher = new FileSystemWatcher(TempDirectory, "*.pdf");
                Directory.SetCurrentDirectory(TempDirectory);
                watcher.Created += new FileSystemEventHandler(OnChanged);
                          
            }
               catch (Exception e)
            {
                LogEvent(e.Message);
                sendDiagnosticWError(e.Message);
                
            }
            finally
            {
                Directory.SetCurrentDirectory(TempDirectory);
                watcher.EnableRaisingEvents = true;
            }
        }
        protected override void OnStop()
        {
            try
            {
                LogEvent("Service Stopped");
                watcher.EnableRaisingEvents = false;
                watcher.Dispose();
            }
            catch (Exception g)
            {
                LogEvent("Error:" + g.Message);
            }
      
            
        }
        protected override void OnPause()
        {
            Directory.SetCurrentDirectory(TempDirectory);
            watcher.EnableRaisingEvents = false;
        }
        protected override void OnContinue()
        {
            Directory.SetCurrentDirectory(TempDirectory);
            watcher.EnableRaisingEvents = true;
        }

Open in new window

Avatar of mmunger

ASKER

Here is the OnChange that is supposed to run when FileWatcher detects a new file in the temp directory:

public static void OnChanged(object source, FileSystemEventArgs e)
        {
//Wait for file to be created
            FileInfo readingFile = new FileInfo(e.Name);
           while (IsFileLocked(readingFile)) { };

//set the current directory
            Directory.SetCurrentDirectory(TempDirectory);
            PDFParser parsePDF = new PDFParser();
            int batchNum = 0;
            string outputFile = "text.txt";
            parsePDF.ExtractText(e.Name, outputFile);
            string fileType = getDocType(e.Name);

            List<LogRow> log = new List<LogRow>();
            if (parsePDF.errorFlag == true)
            {
                LogEvent(parsePDF.error.Message);
                sendDiagnosticWError(parsePDF.error.Message);
            }
            else if (parsePDF.listOfDocs.Count == 0)
            {
                LogEvent("Number of documents returned is < 0.  Please check Crystal Report for special string required for parsing.");
                sendDiagnosticWError("Number of documents returned is < 0.  Please check Crystal Report for special string required for parsing.");
            }
            else
            {
                
                Batch batchOfDocs = new Batch();
                batchOfDocs.NumberOfDocs = parsePDF.listOfDocs.Count;
                batchOfDocs.Type = fileType;
                batchOfDocs.createBatch();
                //set batchNumber for log email
                batchNum = batchOfDocs.getMostRecentBatchNumber();

                try
                {

                    foreach (PDFDocument doc in parsePDF.listOfDocs)
                    {

                        string PDFFileLocation = "C:\\PDFTemp\\ParsedPDF\\" + doc.ID + ".pdf";
                        PdfExtractorUtility extractPDF = new PdfExtractorUtility();
                        Directory.SetCurrentDirectory(TempDirectory);
                        extractPDF.ExtractPages(e.Name, PDFFileLocation, doc.Pages);
                                            
                        LogRow logRow = new LogRow();
                        logRow.BPNumber = doc.BPNum;
                        logRow.DocumentNumber = doc.ID;

                        EDDDocument document = new EDDDocument(doc.ID,fileType,X3Folder);
                        
                        DirectoryStore networkStore = new DirectoryStore(doc.Month, doc.Day, doc.Year);
                        networkStore.createDirectory();

                        //checks if error was thrown when attempting to retrieve email from database
                        if (document.getEmails())
                        {
                            logRow.PrintEmail = "E";
                        }
                        else
                        {
                            FileInfo file2 = new FileInfo(PDFFileLocation);
                            //file2.CopyTo(printer + file2.Name);
                            logRow.PrintEmail = "P";
                            file2.CopyTo(networkStore.location + file2.Name, true);
                        }

                        FileInfo file = new FileInfo(PDFFileLocation);
                        file.CopyTo(networkStore.location + file.Name, true);

                        logRow.EmailAddress = document.EmailAdresses;
                        logRow.Location = networkStore.location + file.Name;
                        log.Add(logRow);

                        Guid uniqueID = System.Guid.NewGuid();
                        
                        PendingTransaction trans = new PendingTransaction(uniqueID, doc.ID, doc.BPNum, document.EmailAdresses, batchNum, false, logRow.PrintEmail, networkStore.location + file.Name);
                      
                    }
                }
                catch (Exception f)
                {
                    LogEvent(f.Message);
                }
                finally
                {
                   if (Directory.Exists(TempDirectory))
                    {
                        clearFolder(TempDirectory);
                    }
                    if (Directory.Exists(ParseDir))
                    {
                        clearFolder(ParseDir);
                    }
       
                }
          
            }
            if (log.Count > 0) { sendDiagnostic(log, batchNum); }
        }

Open in new window

where is your FileSystemEventHandler?
Have you looked in the online help about the FileWatcher class
https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
There is an example there of how to use it
Avatar of mmunger

ASKER

Line 39 in my first code post is where I set the FileSystemEventHandler to fire the Onchanged in my 2nd code snippet.  

Yes, I did review the MSDN information but I it doesn't explain how to setup the FileSystemWatcher as a service.  Like I explained in my original post, my service starts and the Created event does fire my code once when it detects the first file saved to the temp directory.  However, any subsequent file, nothing happens.  It doesn't seem to be catching any errors either.  

Thanks for everyone's comments thus far.

@CreativeTechie
instead of doing all that process in you OnChanged event handler, have you tried just to call something really simple like your LogEvent? Your file might not be ready to be processed when that event is triggered.

Also, have a look at http://emoreau.com/Entries/Articles/2005/04/The-FileSystemWatcher-component.aspx
ASKER CERTIFIED SOLUTION
Avatar of it_saige
it_saige
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mmunger

ASKER

Great solution!  I spent a couple hours looking at this and couldn't figure it out.  I am now writing exceptions to a log file and that seems to have done the trick.