2

I implemented windows service with eventLog and FileSystemWatcher that looks for changes in specific directory and writes messages into MyLog.

strange thing 1:
I install it via installUtil.exe (since the VS2012 doesn't have installer templates) and in some situations when I go to "Services" and start the service I get:

The [service name] service on local computer started and then stopped. Some Services stop automatically if they are not in use by another services or programs.

I've already seen this question. 2 answeres from this post why it can be so:

1) There is no thread starting in OnStart() method.
I use the designer and set most of the properties in the Properties window and I never started any thread manually, but in some cases everything was working, so I think this is not the case.

2) An exception occures in OnStart() method. I think it's not the case cause I don't change the code. I just uninstall, build and install again the same service and in some cases it runs, in some not.

When I was stuck for mabby 2 hours with this thing I noticed that the Source property of eventLog is too long: "FilesMonitoringServices". I changed it to "MonitorSource" and everything started to work. Than I reinstalled it cauple of times and got the same warning as the above. I changed the Source property again and now the service runs.
This is the first strange thing.

strange thing 2: worse. Even if it runs it logs only OnStart() and OnStop() methods, I mean the fileSystemWatcher event handler never excutes. It is strange because today I reinstalled this service mabby hundred times and 3 times it was working but after I reinstalled it once again it stoped. And I haven't changed the code between the reinstallations at all.

Here is the methods and constructor from my class (MonitoringService) that inherits ServiceBase:

public MonitoringService()
    {
        InitializeComponent();

        if (!EventLog.SourceExists(eventLog.Source))
        {
            EventLog.CreateEventSource(eventLog.Source, eventLog.Log);
        }
        // haven't changed it between the reinstallations
        fileWatcher.Path = @"path";                
    }

protected override void OnStart(string[] args)
    {
        fileWatcher.EnableRaisingEvents = true;
        eventLog.WriteEntry("start", EventLogEntryType.Information);
        base.OnStart(args);
    }

    protected override void OnStop()
    {
        fileWatcher.EnableRaisingEvents = false;
        fileWatcher.Dispose();
        eventLog.WriteEntry("stop", EventLogEntryType.Information);
        base.OnStop();
    }

And file system watcher event handler:

private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
    {
        using (var conn = new SqlConnection(GetConnectionString()))
        {
            conn.Open();
            var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value);
            const string cmd = "UPDATE Products SET ImageModifiedDate=@date WHERE ProductId=@productId";
            using (var command = new SqlCommand(cmd, conn))
            {
                command.Parameters.AddWithValue("@productId", productId);
                command.Parameters.AddWithValue("@date", DateTime.Now);
                command.ExecuteNonQuery();
            }                   
        }
        eventLog.WriteEntry(string.Format("{0} has been changed: {1}", e.Name, DateTime.Now), EventLogEntryType.Information);             
    }

Question: it seems to me that this behavior is caused not by my code but rather by operation system settings . Can it be so?

****Edits: just discovered more specific stuff:**

1) If it shows the message (when I want to start the service):

The [service name] service on local computer started and then stopped. ....

I need to change Source property of eventLog, rebuild and reinstall. And this message will not show up; mabby next time.

2) I have the following folders hierarchy: images/prod-images. images and prod-images directories both contain image files. When the service is runing and I change the image from prod-images folder the message is written into the log as I wanted and the database is updated. But after one this event the service stops! (I checked this 3 times). And when I restart it and repeat this again a couple of times it updates database, writes logs and on the 3d time I get

The [service name] service on local computer started and then stopped. ....

But this is not the best part) If I change the image that is in images directory I can do it multiple times and the service doesn't stop. (only images from images/prod-images are bound to entries in the database).

So, mabbe this feature somehow referes to the database accessing?

Edits 2: in visual studio I use DEBUG -> Attach to Process to debug the service. I set up the breakpoints and change the image. First time the event handler executes flawlessly: the database is updated and the log message is written. But than I continue to press F11 (Step Into) and this event handler executes second time. At the line

var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value); 

I get "FormatException was unhandled". After this I stop debugging and the service stops! That's it: the exception occures in event handler.

Do You have any idea why it executes second time? Thanks!

P.S. I've already submited Davut Gürbüz answer cause he pointed me in the right direction.
Anyway, check out my own answer that explains the actual problem.

Community
  • 1
  • 1
Aleksei Chepovoi
  • 3,915
  • 8
  • 39
  • 77

2 Answers2

2

If you got start-stop error, this means you have an error in constructor.

Put a try catch into your ctor. You may log the error to eventlog in catch block.

Beside this I create a main method and start win service as a console app. If I get an instance of service in my main method I can also Debug it.

//You should select Console Application from Application properties
static void Main(string[] args)
    {
        MyWindowsService service = new MyWindowsService();

        if (Environment.UserInteractive)
        {
            service.OnStart(args);
            Console.WriteLine("Press any key to stop program");
            Console.Read();
            service.OnStop();
        }
        else
        {
            ServiceBase.Run(service);
        }

    } 

Hope helps

Davut Gürbüz
  • 5,526
  • 4
  • 47
  • 83
  • now I don't get a start-stop error. The service stops right after I change the image (and there is no entry in log, and the database is not updated). I tried to add try/catch blocks in ctor, OnStart and OnStop methods and log the exception into MyLog - doesn't work. And the service stops as before. – Aleksei Chepovoi Feb 25 '13 at 20:29
  • So just do my second option, use win service as console app, in main method create service and console.readkey not to exit from main. By this way you can run your win service as a console app. Then test it what goes wrong. – Davut Gürbüz Feb 26 '13 at 04:27
  • Is there any error in Windows eventlog ? Even they generally don't show exact cause, So just start it as a console app. Maybe you dispose an object and try to reach ,missed a timer start,...many things can cause – Davut Gürbüz Feb 26 '13 at 04:38
  • I debugged the service and got exception in event handler. Please, check the updated post. – Aleksei Chepovoi Feb 26 '13 at 06:37
  • It seems you get an error http://stackoverflow.com/a/1865798/413032. Beside this I think you don't handle the error so service stops. If you handle where the error occur it mustn't stop. – Davut Gürbüz Feb 26 '13 at 07:02
  • yes, I surrounded the code with try/catch blocks and log the errors. Now the service doesn't stop. – Aleksei Chepovoi Feb 26 '13 at 07:04
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/25123/discussion-between-aleksei-chepovoi-and-davut-gurbuz) – Aleksei Chepovoi Feb 26 '13 at 07:06
0

The reason why the fileSystemWatcher1_Changed event handler method was executing twice is because I was monitoring images folder included subdirectories. And this event handler was monitoring all LastWrite events.

So, when I changed the image in images/prod-images directory this handler reacted to the image changing and also to the folder changing.

In this situation I either can change the monitoring path to prod-images or insert an if statement when updating the DB.

Such a silly mistake took me a couple of days to find it out))

Aleksei Chepovoi
  • 3,915
  • 8
  • 39
  • 77