• 再谈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

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

    技术改变世界
  • 相关阅读:
    少有人走的路-与心灵对话-斯科特·派克
    少有人走的路-勇敢地面对谎言-斯科特·派克
    LayUI单图片、多图片上传,layEditor上传图片
    LayUI多tab栏列表单条数据按钮操作
    LayUI多tab栏无刷新分页
    LayUI异步分页
    xshell远程链接centOS8一直提示服务器拒绝密码,请再试一次
    ios dylib反检测系统api
    配置 LaTeX 公式自动补全
    LaTeX 公式手册(按年级分类)
  • 原文地址:https://www.cnblogs.com/davidgu/p/2585057.html
Copyright © 2020-2023  润新知