Link to home
Create AccountLog in
Avatar of randycdouglas
randycdouglasFlag for United States of America

asked on

Simple Windows Service not starting

My simple windows service isn't starting. I've been trying to install it locally (Windows 7 64 bit) to test. VS 2010 & C# & 64 bit. My solution properties list the active config as Debug|x86; there's not option for x64. Is this a problem? I've created an installer for the service by following these steps: http://msdn.microsoft.com/en-us/library/zt39148a.aspx. Start Type is set to automatic. My ServiceProcessInstaller is using the LocalSystem account. Please help me figure out why this service won't start.
using System;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;

namespace dupzapII
{
    public partial class DupZap : ServiceBase
    {
        private FileSystemWatcher _watcher;
        private string watchFolder = @"C:\FolderBeingWatched\";
        private string destinationFolder = @"C:\FolderToMoveTo\";

        public DupZap()
        {
            InitializeComponent();

            if (!System.Diagnostics.EventLog.SourceExists("DupZap"))
            {
                System.Diagnostics.EventLog.CreateEventSource(
                    "DupZap", "DupZap");
            }

            eventLog1.Source = "DupZap";
            eventLog1.Log = "DupZap";
        }

        protected override void OnStart(string[] args)
        {
            eventLog1.WriteEntry("DupZap Started");

            try
            {
                _watcher = new FileSystemWatcher(watchFolder, "*.tif");

                _watcher.Changed += new FileSystemEventHandler(watcher_FileChanged);
                _watcher.NotifyFilter = NotifyFilters.LastWrite;
                _watcher.EnableRaisingEvents = true;
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.ToString(), EventLogEntryType.Error);
            }
        }

        void watcher_FileChanged(object sender, FileSystemEventArgs e)
        {
            try
            {
                eventLog1.WriteEntry("DupZap Started");

                File.Move(e.FullPath, e.FullPath.Replace(watchFolder, destinationFolder));
            }

            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.ToString(), EventLogEntryType.Error);
            }
        }

        protected override void OnStop()
        {
            eventLog1.WriteEntry("DupZap Stopped");
        }
    }
}

Open in new window

Avatar of randycdouglas
randycdouglas
Flag of United States of America image

ASKER

When trying to start it after I install I get the following message.

"The DupZap service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs."
The purpose of the service, without getting into to much detail, is to watch a folder, once a file (tif image) is copied to it, the file will be moved to another folder. Later I'll be checking the destination folder for a duplicate of the inserted file.
Avatar of kaufmed
There is no "work" for your service to do--an event handler isn't enough to keep your service alive. An event handler only exists as long as your application exists, and since there is nothing to keep your service in memory, you get the behavior you have experienced.

What I mean by "work" is that you need to either spawn a new thread, or start a timer. You do either of these options in your OnStart method. Since it appears that the whole of your service is to let the FileSystemWatcher do its thing, I'd say all you need is a polling loop. All the loop needs to do is sleep. For example,

while (true)
{
    System.Threading.Thread.Sleep(1000);
}

Open in new window


Now this is very basic, and it doesn't really give you a way to cleanly stop the thread, but it should give you an idea of what needs to happen for your service to run.
Thanks expert! This makes sense, but I tried it with no success. I got the same message I listed in my original post. I've listed the two different ways I tried your suggestion. See anything else that could be causing this?

Also, I see you wrote "it doesn't really give you a way to cleanly stop the thread". Why is this required and how is this done. Your help is greatly appreciated.
protected override void OnStart(string[] args)
{
    eventLog1.WriteEntry("DupZap Started");

    try
    {
        while (true)
        {                    
            _watcher = new FileSystemWatcher(watchFolder, "*.tif");

            _watcher.Changed += new FileSystemEventHandler(watcher_FileChanged);
            _watcher.NotifyFilter = NotifyFilters.LastWrite;
            _watcher.EnableRaisingEvents = true;

            Thread.Sleep(1000);
        }
    }
    catch (Exception ex)
    {
        eventLog1.WriteEntry(ex.ToString(), EventLogEntryType.Error);
    }
}

I've also tried this:
protected override void OnStart(string[] args)
{
    eventLog1.WriteEntry("DupZap Started");

    try
    {
        _watcher = new FileSystemWatcher(watchFolder, "*.tif");

        _watcher.NotifyFilter = NotifyFilters.LastWrite;
        _watcher.EnableRaisingEvents = true;

        while (true)
        { 
            _watcher.Changed += new FileSystemEventHandler(watcher_FileChanged);                    

            Thread.Sleep(1000);
        }
    }
    catch (Exception ex)
    {
        eventLog1.WriteEntry(ex.ToString(), EventLogEntryType.Error);
    }
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of kaufmed
kaufmed
Flag of United States of America image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
I see. Things are so much clearer now. I was under the impression a service would continue to run on its own.

Unfortunatly, I'm still getting the same error. My new code is listed below. Your time is appreciated.
using System;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using System.Threading;

namespace dupzapII
{
    public partial class DupZap : ServiceBase
    {
        private FileSystemWatcher _watcher;
        private string watchFolder = @"C:\FolderBeingWatched\";
        private string destinationFolder = @"C:\FolderToMoveTo\";
        private System.Threading.Thread workerThread;
        private bool keepRunning;

        public DupZap()
        {
            InitializeComponent();

            if (!EventLog.SourceExists("DupZap"))
            {
                EventLog.CreateEventSource(
                    "DupZap", "DupZap");
            }

            eventLog1.Source = "DupZap";
            eventLog1.Log = "DupZap";
        }

        protected override void OnStart(string[] args)
        {
            eventLog1.WriteEntry("DupZap Started");

            try
            {
                _watcher = new FileSystemWatcher(watchFolder, "*.tif");

                _watcher.NotifyFilter = NotifyFilters.LastWrite;
                _watcher.EnableRaisingEvents = true;

                this.keepRunning = true;
                this.workerThread = new System.Threading.Thread(RunWorkerLoop);
                this.workerThread.Start();
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.ToString(), EventLogEntryType.Error);
            }
        }

        void watcher_FileChanged(object sender, FileSystemEventArgs e)
        {
            try
            {
                eventLog1.WriteEntry("DupZap Started");

                File.Move(e.FullPath, e.FullPath.Replace(watchFolder, destinationFolder));
            }

            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.ToString(), EventLogEntryType.Error);
            }
        }

        protected override void OnStop()
        {
            this.keepRunning = false;
            eventLog1.WriteEntry("DupZap Stopped");
        }

        private void RunWorkerLoop()
        {
            while (this.keepRunning)
            {
                System.Threading.Thread.Sleep(1000);
            }
        }
    }
}

Open in new window

I copied your code into a new project and it worked fine for me. The only issue I see is that you haven't attached the handler to the event. In other words, you are missing a line like this:

_watcher.Changed += new FileSystemEventHandler(watcher_FileChanged);

Open in new window


Other than that, it should be working. What account are you running the service as? A local account? LOCAL SERVICE? NETWORK SERVICE? etc.?
My ServiceProcessInstaller is using the LocalSystem account.
Are you certain you are uninstalling the old service and reinstalling the new, rebuilt version?
Copying the code into a new project did the trick. Thanks expert!