?
Solved

Windows Service that monitors a folder

Posted on 2004-11-04
9
Medium Priority
?
4,667 Views
Last Modified: 2008-01-09
Hi everyone

I'm trying to create a Windows Service that monitors a given directory.  Whenever a file is dropped inside that directory, it processes that file.

When I created this service (using the walkthrough on MSDN) and installed it, it timed out when I tried to start it.  It *was* processing the files dropped in the directory, but its status in the MMC was "starting" rather than "started."

I'm assuming I need to return control to the OS somehow, but how?  I thought FileSystemWatcher is non-blocking.  Do I need to launch a new thread?

Here's the main monitoring function for my application (called through OnStart in the service):

private void Monitor(string path)
{
  // The file monitor for the semaphore directory
  FileSystemWatcher watcher = new FileSystemWatcher(path);

  watcher.NotifyFilter = NotifyFilters.LastWrite |
    NotifyFilters.DirectoryName | NotifyFilters.FileName;
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.EnableRaisingEvents = true;

    // Wait for changes in the semaphore directory
    while(true)
    {
      watcher.WaitForChanged(WatcherChangeTypes.All);
    }
}
0
Comment
Question by:yizchaknaveh
  • 2
  • 2
  • 2
  • +3
9 Comments
 
LVL 8

Expert Comment

by:AaronReams
ID: 12500875
You should do your Monitor in a separate thread so the call to OnStart can return successfully to the service manager.

WaitForChange is a blocking/synchronous function.  However, even if it was asynchronous/non-blocking, your code would effectively make it blocking because of the infinite while loop.

So just fire up a separate thread and you're good to go.

Hope this helps.
-Aaron
0
 
LVL 9

Expert Comment

by:s_sansanwal
ID: 12500879
You need to run this in a separate thread as your application is stuck in While loop

Cheers,
S Sansanwal
0
 
LVL 9

Assisted Solution

by:s_sansanwal
s_sansanwal earned 400 total points
ID: 12500892
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 8

Assisted Solution

by:AaronReams
AaronReams earned 800 total points
ID: 12500956
This should help you get started with a thread so your service can start succesfully.  Cheers -A.

private void Monitor(string path)
{
       ServerInstanceThread s = new ServerInstanceThread(path);
       Thread sThread = new Thread(new ThreadStart(s.ThreadProc));
       sThread.IsBackground = true;
       sThread.Start();
}

public class ServerInstanceThread
{
     public string path;
     public ServerInstanceThread(string _path)  { path = _path;}

      public void ThreadProc()
      {
           // The file monitor for the semaphore directory
           FileSystemWatcher watcher = new FileSystemWatcher(path);

          watcher.NotifyFilter = NotifyFilters.LastWrite |
          NotifyFilters.DirectoryName | NotifyFilters.FileName;
          watcher.Created += new FileSystemEventHandler(OnChanged);
          watcher.EnableRaisingEvents = true;

          // Wait for changes in the semaphore directory
          while(true)
          {
              watcher.WaitForChanged(WatcherChangeTypes.All);
          }  
      }
}
0
 
LVL 19

Expert Comment

by:Fahad Mukhtar
ID: 12501311
There is no need for this listener Loop you can acheive the funcitionlaity without this:

   // Wait for changes in the semaphore directory
   while(true)
   {
     watcher.WaitForChanged(WatcherChangeTypes.All);
   }
0
 
LVL 19

Accepted Solution

by:
Fahad Mukhtar earned 800 total points
ID: 12501321
Heres what i did for a similar Windows Service i suppose...


protected override void OnStart(string[] args)
            {                  
                  Watcher = new FileSystemWatcher();
            Watcher.Path = ReportsPhysicalFolder ;//put your folder to watch here

                  Watcher.NotifyFilter = NotifyFilters.DirectoryName;
                  Watcher.NotifyFilter = Watcher.NotifyFilter | NotifyFilters.FileName;
                  Watcher.NotifyFilter = Watcher.NotifyFilter | NotifyFilters.Attributes;

                  //add the handler to each event                  
                  
                  Watcher.Changed +=  new FileSystemEventHandler (this.  logchange);
                  Watcher.Created +=  new FileSystemEventHandler (this.  logchange);
                  Watcher.Deleted +=  new FileSystemEventHandler (this.  logchange);

                  // add the rename handler as the signature is different
                  Watcher.Renamed += new  RenamedEventHandler  (this.  logrename);

                  //Set this property to true to start watching
                  Watcher.EnableRaisingEvents = true;            
            }
 
            /// <summary>
            /// Stop this service.
            /// </summary>
            ///             
            protected override void OnStop()
            {
                  Watcher.EnableRaisingEvents = false;
            }

            private void logchange ( object source , FileSystemEventArgs e)
            
            {      
                  try
                        {
                              if (e.ChangeType == WatcherChangeTypes.Created)
                              {
                                    ServiceWriteToFile ("NEW REPORT!!! Report \"" + e.Name + "\" has been added to the Application.");                              
                              }
       
                              if (e.ChangeType == WatcherChangeTypes.Deleted )
                              {
                                    ServiceWriteToFile ("REPORT DELETED!!! Report \"" + e.Name + "\" has been removed from the Application.");
                              }
                        }

                        catch (XmlException rr)
                        {
                              ServiceWriteToFile("XML ERROR Occured During Processing  : " + rr.Message +  RecordSepartor + "\r\n");
                        }

                        catch (SqlException ss)
                        {
                              ServiceWriteToFile("DATABASE ERROR Occured During Processing : " + ss.Message +  RecordSepartor + "\r\n");                              
                        }                        
                        
                        catch (Exception ss)
                        {
                              ServiceWriteToFile("ERROR Occured During Processing : " + ss.Message +  RecordSepartor + "\r\n");                              
                        }
            }

            private void logrename ( object source , RenamedEventArgs e)
            {
                        try
                        {
                              ServiceWriteToFile ("REPORT NAME CHANGED!!! Report \"" + e.OldName + "\" has been renamed to \"" + e.Name + "\"");
                        }

                        catch (XmlException rr)
                        {
                              ServiceWriteToFile("XML ERROR Occured During Processing  : " + rr.Message +  RecordSepartor + "\r\n");
                        }

                        catch (SqlException ss)
                        {
                              ServiceWriteToFile("DATABASE ERROR Occured During Processing : " + ss.Message +  RecordSepartor + "\r\n");                              
                        }                        
                        
                        catch (Exception ss)
                        {
                              ServiceWriteToFile("ERROR Occured During Processing : " + ss.Message +  RecordSepartor + "\r\n");                              
                        }
            
            }


ServiceWriteToFile()  is my user defined function
0
 
LVL 8

Expert Comment

by:Razzie_
ID: 12502666
Hi yizchaknaveh,

I, and other people, have experienced the exact same problems when starting a windows server. Take a look at this question:

http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21133967.html

I gave some possible solutions there that helped me and some other people. I advice you give it a shot. As far as I know, this is not a problem with your code in anyway, but rather a bug in Windows. Let me guess, are you installing the service under Windows 2000?

Cheers,

Razzie
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 12506859
The OnStart() method is called while starting your service. You are not supposed to block or take control at this point because if you do you will never return control to ServiceBase to allow for the completion of the start process.
0
 

Author Comment

by:yizchaknaveh
ID: 12509657
Wow!  Thanks to all who responded.  The app works now, and I got rid of the ugly infinite loop. :)

Points split.

Razzie: no, I was installing on XP Pro
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question