技术开发 频道

如何创建一个标准的Windows服务

  3.服务操作
  首先需要创建一个集成自System.ServiceProcess.ServiceBase的服务类,如SocketService服务类,在SocketService类的构造函数中,您可能需要初始化一些信息,如创建一个定时器,修改服务器类的名称,读取配置参数等信息,以便初始化服务类的参数。
接着您需要重载服务基类的一些函数:OnStart、OnStop、OnContinue、OnPause、OnShutdown和定时器的触发函数timerReAlarm_Elapsed。完整的类如下:

public class SocketService : ServiceBase
    {
        
private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        
private AppConfig appConfig = new AppConfig();
        
private System.Timers.Timer timerReAlarm;

        
private int ServiceCycle = 1;//服务运行间隔,和整点运行相斥(单位分钟)
        private int CycleCount = 0;//间隔的服务运行计数(单位分钟)

        
private int ServiceRunAt = 0;//整点运行服务时间,负数为禁用(单位小时)
        private bool RunAtOnce = false;//整点运行服务是否已经运行

        
private bool GBLService = false;//是否启动GBL同步服务
        private bool DomainService = false;//是否启动域用户同步

        
/// <summary>
        
/// 必需的设计器变量。
        
/// </summary>
        private System.ComponentModel.IContainer components = null;
        
private System.Diagnostics.EventLog eventLog;

        
public SocketService()
        {
            InitializeComponent();

            eventLog
= new EventLog();
            eventLog.Log
= "Application";
            eventLog.Source
= Constants.ServiceName;

            
this.ServiceName = Constants.ServiceName;

            
try
            {
                
//系统心跳
                int interval = int.Parse(appConfig.AppConfigGet("TimerInterval"));
                interval
= (interval < 1) ? 1 : interval;//不能太小
                timerReAlarm = new System.Timers.Timer(interval * 60000);//分钟
                timerReAlarm.Elapsed += new ElapsedEventHandler(timerReAlarm_Elapsed);

                
//服务运行间隔
                ServiceCycle = int.Parse(appConfig.AppConfigGet("ServiceCycle"));
                ServiceCycle
= (ServiceCycle < interval) ? interval : ServiceCycle;//不能小于心跳

                
//服务整点运行
                ServiceRunAt = int.Parse(appConfig.AppConfigGet("ServiceRunAt"));

                GBLService
= Convert.ToBoolean(appConfig.AppConfigGet("GBLService"));
                DomainService
= Convert.ToBoolean(appConfig.AppConfigGet("DomainService"));

                logger.Info(Constants.ServiceName
+ "已初始化完成");
            }
            
catch (Exception ex)
            {
                logger.Error(Constants.ServiceName
+ "初始化错误", ex);
            }
        }

        
/// <summary>
        
/// 设置具体的操作,以便服务可以执行它的工作。
        
/// </summary>
        protected override void OnStart(string[] args)
        {
            logger.Info(Constants.ServiceName
+ "开始启动。");

            timerReAlarm.Start();          
            eventLog.WriteEntry(Constants.ServiceName
+ "已成功启动。", EventLogEntryType.Information);

            CreateTask();
        }

        
/// <summary>
        
/// 停止此服务。
        
/// </summary>
        protected override void OnStop()
        {
            timerReAlarm.Stop();
        }

        
/// <summary>
        
/// 暂停后继续运行
        
/// </summary>
        protected override void OnContinue()
        {
            timerReAlarm.Start();
            
base.OnContinue();
        }

        
/// <summary>
        
/// 暂停
        
/// </summary>
        protected override void OnPause()
        {
            timerReAlarm.Stop();
            
base.OnPause();
        }

        
/// <summary>
        
/// 关闭计算机
        
/// </summary>
        protected override void OnShutdown()
        {
            
base.OnShutdown();
        }

        
private void timerReAlarm_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            CreateTask();
        }


        
/// <summary>
        
/// 使用线程池方式运行程序
        
/// 优点:快速启动Windows服务, 在后台继续程序操作.
        
/// </summary>
        private void CreateTask()
        {
            ThreadPool.QueueUserWorkItem(
new WaitCallback(ExecuteTask), null);
        }

        
/// <summary>
        
/// 开始执行同步任务
        
/// </summary>    
        private void ExecuteTask(object status)
        {
            
try
            {
                
//采用整点运行方式
                if(ServiceRunAt > 0)
                {
                    
if(DateTime.Now.Hour == ServiceRunAt)
                    {
                        
if(!RunAtOnce)
                        {
                            Execute();
                            RunAtOnce
= true;//标识整点已经运行过了
                        }
                    }
                    
else
                    {
                        RunAtOnce
= false;
                    }

                }
                
else//采用间隔运行方式
                {
                    
//不管服务间隔是否心跳的倍数,只要服务间隔时间大于等于间隔时间,就执行一次
                    if(CycleCount >= ServiceCycle)
                    {
                        Execute();
                        CycleCount
= 0;
                    }
                    
else
                    {
                        CycleCount
++;
                    }
                }
            }
            
catch (Exception ex)
            {
                logger.Error(
"ExecuteTask()函数发生错误", ex);
                eventLog.WriteEntry(Constants.ServiceName
+ "运行时出现异常!\r\n" + ex.Message + "\r\n" + ex.Source + "\r\n" + ex.StackTrace);
            }
        }

        
public void Execute()
        {
            
//初始化数据库连接
            string DatabasePassword = Sys.decode(ConfigurationSettings.AppSettings.Get("DatabasePassword"));
            DAO.init(ConfigurationSettings.AppSettings.Get(
"DatabaseConnect").Replace("{$password}", DatabasePassword), DAO.DATABASE_SQLSERVER); //初始化数据库(SQL Server)访问对象
            Lib.adPasswd = Sys.decode(ConfigurationSettings.AppSettings.Get("password"));    
            
            
if(GBLService)
            {
                AutomatismXml xml
= new AutomatismXml();
                xml.AutomatismXmlData(
0);

                logger.Info(Constants.ServiceName
+ DateTime.Now.ToShortTimeString() + "已成功调用了GBLService一次。");
                eventLog.WriteEntry(DateTime.Now.ToShortTimeString()
+ "已成功调用了GBLService一次。", EventLogEntryType.Information);
            }
            
if(DomainService)
            {
                
string msg = string.Empty;
                
string path = ConfigurationSettings.AppSettings.Get("path");
                
string username = ConfigurationSettings.AppSettings.Get("username");
                
string domain = ConfigurationSettings.AppSettings.Get("domain");
                AD.init(path, username, Lib.adPasswd, domain);

                DomainHelper.accountSync(
true, false, true, ref msg, 1);
                Log.saveADLog(
null, "系统同步域用户:" + msg);

                logger.Info(Constants.ServiceName
+ DateTime.Now.ToShortTimeString() + "已成功调用了DomainService一次。");
                eventLog.WriteEntry(DateTime.Now.ToShortTimeString()
+ "已成功调用了DomainService一次。", EventLogEntryType.Information);
            }
        }

        ...................
    }

 


   

0
相关文章