将C#控制台应用程序转换为服务

7

我正在尝试将一个控制台应用程序转换为Windows服务。我想让服务的OnStart方法调用我的类中的一个方法,但是我似乎无法使它正常工作。我不确定自己是否做对了。请问在服务中应该把类信息放在哪里?

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

来自评论:

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);
  }
 }
}

你把项目类型从控制台应用程序改成了Windows应用程序吗?你是否正在调用ServiceBase.Run - Trevor Elliott
是的,我在我的解决方案中创建了一个新项目作为Windows服务。 - user2892443
命名空间 MyService { static class serviceProgram { /// <summary> /// 应用程序的主入口点。 /// </summary> static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new Service1() }; ServiceBase.Run(ServicesToRun); } } } - user2892443
2个回答

8

Windows服务的{{MSDN文档}}非常好,包含了你需要开始使用的所有内容。

你遇到的问题是由于你的OnStart实现引起的,它仅应用于设置服务以便准备就绪,该方法必须迅速返回。通常你会在另一个线程或计时器中运行大部分代码。参见OnStart页面进行确认。

编辑:如果不知道你的Windows服务将要做什么,很难告诉你如何实现,但假设你想在服务运行时每10秒运行一次方法:

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;
    }
}

在这里,OnStart方法在设置计时器后立即返回,TimerOnElapsed将在工作线程上运行。我还添加了一个调用System.Diagnostics.Debugger.Launch();,这将使调试变得更加容易。
如果您有其他要求,请编辑您的问题或发布评论。

这是我的问题,我不确定在OnStart实现中应该放什么。你说的把大部分代码放在单独的线程或计时器上是什么意思?如果不是从OnStart调用我的代码,那么进程怎么知道要运行我的代码呢?非常感谢您的耐心,服务对我来说是全新的。 - user2892443
1
@user2892443 通过示例修改了我的回答。 - ChrisO

3

做自己最大的一个好处就是使用topshelfhttp://topshelf-project.com/来创建你的服务。我没有看到比这更容易的工具了。他们的文档非常出色,部署也非常简单。c:/path to service/service.exe install.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接