再谈Windows Service - 一个简单的自我例子和部署

我们的服务需要做两件自动的事情,一个是往表格中定时插入数据,另一个就是

往文件中定时插入内容

 

因此,我们需要做一个工作类,这个类可以是一个抽象类,如下:

TaskWorker

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;

namespace WinConsoleService
{
    public abstract class TaskWorker
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(TestTaskWorker));

        public bool Pause { getset; }

        public bool Stop { getset; }

        public abstract void Run();
    }
}

 

我们实际的工作任务是需要继承该抽象类的两个实体类,如下:

DbTaskWorker

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using WinConsoleService.DAL;
using System.Configuration;
using System.Diagnostics;
using log4net;

namespace WinConsoleService
{
    public class DbTaskWorker: TaskWorker
    {
        //private static readonly ILog logger = LogManager.GetLogger(typeof(TestTaskWorker));

        public bool Pause { getset; }

        public bool Stop { getset; }

        public override void Run()
        {
            //logger.Info("Test Task Work Started ...");
            
            while (!Stop)
            {
                if (Pause)
                    continue;
 
                Do();
                
                Thread.Sleep(int.Parse(ConfigurationManager.AppSettings["WakeupInterval"]));
            }
        }

        private void Do()
        {
            
            SqlDbUtil db = new SqlDbUtil();
            string sql = @"insert into Test2
                            values('1', '2' , '3')
";
            int ret = db.ExecuteSQL(sql);

            if (ret == -1)
                FileUtil.WriteLog("Exception: database insert error!");
        }
    }
}

 

FileTaskWorker

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using log4net;

namespace WinConsoleService
{
    public class FileTaskWorker : TaskWorker
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(FileTaskWorker));

        public override void Run()
        {
            while (!Stop)
            {
                if (Pause)
                    continue;

                Do();

                Thread.Sleep(int.Parse(ConfigurationManager.AppSettings["WakeupInterval"]));
            }
        }

        private void Do()
        {
            FileStream fs = new FileStream("E:\\PerformanceLog_" + DateTime.Now.ToString("yyyyMMdd") + ".log", FileMode.Append);
            StreamWriter streamWriter = new StreamWriter(fs);
            streamWriter.BaseStream.Seek(0, SeekOrigin.End);
            streamWriter.WriteLine(DateTime.Now);
            streamWriter.Flush();
            streamWriter.Close();
        }
    }
}

 

 由于Windows Service调试起来比较困难,因此我做了一个文件日志,本来

考虑用log4net,但是log4net经常抽疯,所以还是自己做一个吧

FileUtil

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace WinConsoleService
{
    public class FileUtil
    {
        public static void WriteLog(string ex)
        {
            /*
            FileStream fs = new FileStream("C:\\test.log", FileMode.Append);
            StreamWriter streamWriter = new StreamWriter(fs);
            streamWriter.BaseStream.Seek(0, SeekOrigin.End);
            streamWriter.WriteLine(ex);
            streamWriter.Flush();
            
*/

            StreamWriter sw = File.AppendText("C:\\test.log");
            sw.WriteLine(ex);
            sw.Close();


        }
    }
}

 

服务主体代码如下:

Service1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Threading;

using log4net;

namespace WinConsoleService
{
    public partial class Service1 : ServiceBase
    {
        private TaskWorker worker;
        ILog logger = LogManager.GetLogger(typeof(Service1));

        public Service1()
        {
            FileUtil.WriteLog("Windows Service Start");

            InitializeComponent();
            this.worker = new FileTaskWorker();

            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 
        }

        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {

                Exception ex = e.ExceptionObject as Exception;
                FileUtil.WriteLog("来自Service1的全局异常, " + ex.Message + "详细信息如下:"
                                    + Environment.NewLine + "[InnerException]" + ex.InnerException
                                    + Environment.NewLine + "[Source]" + ex.Source
                                    + Environment.NewLine + "[TargetSite]" + ex.TargetSite
                                    + Environment.NewLine + "[StackTrace]" + ex.StackTrace);
            }
            catch { }
        }
        
        protected override void OnStart(string[] args)
        {
            FileUtil.WriteLog("OnStart");
            Thread t = new Thread(new ThreadStart(this.worker.Run));
            t.Start();
        }

        protected override void OnStop()
        {
            FileUtil.WriteLog("OnStop");

            this.worker.Stop = true;
            this.worker.Pause = true;
        }

        protected override void OnPause()
        {
            FileUtil.WriteLog("OnPause");
            this.worker.Pause = true;
        }

        protected override void OnContinue()
        {
            FileUtil.WriteLog("OnContinue");
            this.worker.Pause = false;
        }
    }
}

 

 控制台入口

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using log4net.Config;

namespace WinConsoleService
{
    static class Program
    {
        /// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>
        static void Main()
        {
            XmlConfigurator.Configure();
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new Service1() 
            };
            ServiceBase.Run(ServicesToRun);
        }
    }
}

 

 最后,再次谈一下部署

首先,如果你用的是.NET4.0, 需要找到该目录:

C:\Windows\Microsoft.NET\Framework\v4.0.30319

然后,记住一定要把该路径添加到环境变量的path路径

 

如果是windows7的用户, 请记住一定要在管理员情况下运行Visual Studio Command Prompt

 

然后,把你Debug目录下的文件统统拷贝到记得服务目录,运行该命令

cd 服务目录

InstallUtil WinConsoleService.exe

 

这样,服务就部署完成了,以后重新修改服务,只要停止服务,覆盖原来的文件就好了

 

 

 

 

posted @ 2012-07-10 17:48  Master HaKu  阅读(960)  评论(0编辑  收藏  举报