C# Converting Console App to Service
Asked Answered
S

2

7

I am trying to convert a console app to a Windows service. I am trying to have the onstart method of the service call a method in my class but I can;t seem to get it to work. I'm not sure I am doing this correctly. Where do I put the class information in the service

protected override void OnStart(string[] args)
{
   EventLog.WriteEntry("my service started");
   Debugger.Launch();
   Program pgrm = new Program();
   pgrm.Run();
}

From the comment:

namespace MyService {
 static class serviceProgram {
  /// <summary> 
  /// The main entry point for the application. 
  /// </summary> 
  static void Main() {
   ServiceBase[] ServicesToRun;
   ServicesToRun = new ServiceBase[] {
    new Service1()
   };
   ServiceBase.Run(ServicesToRun);
  }
 }
}
Speedwell answered 17/10, 2013 at 22:26 Comment(3)
Did you change the project type from Console Application to Windows Application? Are you calling ServiceBase.Run?Fury
Yes I created a new project in my solution as a Windows service.Speedwell
namespace MyService { static class serviceProgram { /// <summary> /// The main entry point for the application. /// </summary> static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new Service1() }; ServiceBase.Run(ServicesToRun); } } }Speedwell
O
8

The MSDN documentation on Windows Services is really good and has everything you need to get started.

The problem you're having is because of your OnStart implementation, that's only supposed to be used to set up the service so it's ready to start, the method must return promptly. Usually you'd run the bulk of the code on another thread or in a timer. See the page for OnStart for confirmation.

Edit: Without knowing what your windows service will do, it's hard to tell you how to implement it but let's say you wanted to run a method every 10 seconds while the service is running:

public partial class Service1 : ServiceBase
{
    private System.Timers.Timer _timer; 

    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
#if DEBUG
        System.Diagnostics.Debugger.Launch(); // This will automatically prompt to attach the debugger if you are in Debug configuration
#endif

        _timer = new System.Timers.Timer(10 * 1000); //10 seconds
        _timer.Elapsed += TimerOnElapsed;
        _timer.Start();
    }

    private void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
    {
        // Call to run off to a database or do some processing
    }

    protected override void OnStop()
    {
        _timer.Stop();
        _timer.Elapsed -= TimerOnElapsed;
    }
}

Here, the OnStart method returns immediately after setting up the timer and TimerOnElapsed will be run on a worker thread. I also added a call to System.Diagnostics.Debugger.Launch(); which will make debugging alot easier.

If you have some other requirements, please edit your question or post a comment.

Openeyed answered 17/10, 2013 at 22:52 Comment(2)
Thats my problem, Im not sure what to put in the OnStart Implementation. What do you mean put the bulk of the code on a seperate thread or timer? How does the process know to run my code if its not called from OnStart. Thank you in advance for patience, Services are completely new to meSpeedwell
@Speedwell Edited my answer with an example.Openeyed
E
3

Do yourself the biggest favor and use topshelf http://topshelf-project.com/ to create your service. There is nothing easier that I have seen. Their documentation is supperb and deployment could not be simplier. c:/path to service/service.exe install.

Enenstein answered 17/10, 2013 at 22:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.