简体   繁体   中英

C# Windows Service: The service did not respond to the start

This is my first attempt at creating a Windows service that calls multiple threads. What i did was create a console app, then added a windows service and installer to it. My code is below.

partial class Service1 : ServiceBase
{
    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        System.Timers.Timer timer1 = new System.Timers.Timer();
        timer1.Interval = 10000;
        timer1.Start();
        timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
    }

    public static void timer1_Elapsed(object sender, EventArgs e)
    {
        Program.ThreadController();   
    }

    protected override void OnStop()
    {
        // TODO: Add code here to perform any tear-down necessary to stop your service.
    }
}

class Program
{
    static void Main(string[] args)
    {
        ThreadController();
    }

    public static void ThreadController()
    {
        for (int i = 0; i < 3; i++)
        {
            new Thread(() => { processEventLogTesting(); });
        }
    }

    public static void processEventLogTesting()
    {
        EventLog.WriteEntry("ProcessThread1", "Process1 Works");
    }
}

I'm not sure why i'm getting this error, any hints would be awesome.

Thanks.

You have infinite recursion in processEventLogTesting () . That's why it's not responding. When I write a Windows service with a timer, all I do is wire the callback and start the timer in the OnStart. Then I sit back and let it do its thing. You are trying to do too much on startup.

First I'd add in some capability to do debugging. It's actually easy (when you know how.!!).

Add this to your class:

[DllImport("kernel32.dll")]
public static extern Int32 AllocConsole();

Then add this to your main function (and you CAN do this too when running as a service if you enable the service to access the user interface by the way).

for (int loop = 0; loop < args.Count; loop++)
{
  if (args[loop] == "debug")
    AllocConsole();
}

This gives you a console window and you can use Console.WriteLine to send output to it now. Yummy.

Now what you want to achieve, is for the service control manager to call your OnStart method, and then that method must RETURN the OK signal to let the SCM know that your app started up ok. Otherwise, SCM thinks something is wrong and kills your app. So OnStart is supposed to start your threads. So, make a Run() method that gets run by your thread (and by Main), and make OnStart return as fast as you can.

I notice I don't see any of this in your code example:

System.ServiceProcess.ServiceBase[] ServicesToRun; ServicesToRun = new System.ServiceProcess.ServiceBase[] { new WinService1() }; System.ServiceProcess.ServiceBase.Run(ServicesToRun);

I suspect that your app isn't reporting to the SCM that it has successfully launched the "service" that is inside your executable.

You want your app to fire up, hand off the "service" to the SCM and let it know you are ok, and then return, while your service is now running with its own thread.

See this article for a great walk through: http://msdn.microsoft.com/en-us/library/aa984464(v=vs.71).aspx

 partial class Service1 : ServiceBase
 {
    private Program program;

    public Service1()
    {
        InitializeComponent();
        program = new Program ();
    }

    protected override void OnStart(string[] args)
    {
        program.Start ();
    }

    protected override void OnStop()
    {
        program.Stop ();
    }
}

class Program
{
    private Systems.Timers.Timer timer;

    public Program ()
    {
        timer = new System.Timers.Timer ();
        timer.Interval = 10000;
        timer.Elapsed += new ElapsedEventHandler (timer_Elapsed);

    }

    public void Start () 
    {
        timer.Enabled = true;
    }

    public void Stop ()
    {
        timer.Enabled = false;
    }

    public static void timer_Elapsed (object sender, EventArgs e)
    {
        EventLog.WriteEntry ("ProcessThread1", "Process1 Works");
    }
}
  1. You don't start the Threads at your code, so:

     for (int i = 0; i < 3; i++) { new Thread(() => { processEventLogTesting(); }) { IsBackground = true }.Start(); }
  2. At your processEventLogTesting() in addition to your wrong recursive call, you are creating a timer and then just override it by timer1 = new System.Timers.Timer();so it will not fire.

     public static void processEventLogTesting() { System.Timers.Timer timer1 = new System.Timers.Timer(); timer1.Interval = 10000; timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed); timer1.Start(); }

Windows services are notoriously difficult to debug. If you are not getting any other messages, try putting a pause on the onstart, and you should be able to attach to it, and then see what the problem is.

Nik has the answer here, but this may be useful for other windows services!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM