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

简介: 我们的服务需要做两件自动的事情,一个是往表格中定时插入数据,另一个就是往文件中定时插入内容 因此,我们需要做一个工作类,这个类可以是一个抽象类,如下:TaskWorkerusing System;using System.

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

往文件中定时插入内容

 

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

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 {  get;  set; }

         public  bool Stop {  get;  set; }

         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 {  get;  set; }

         public  bool Stop {  get;  set; }

         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

 

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

 

 

 

 

目录
相关文章
|
存储 数据安全/隐私保护 Windows
Windows中部署网盘神器 Filebrowser
ZeroNews (零讯)内网穿透赋予 FileBrowser 任意位置互联网访问的能力,无需用户具备固定公网IP,提供专用的访问域名,将 FileBrowser 转变为公有云盘,实现多用户在线协同工作。
|
Linux C++ Windows
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
490 0
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
|
JSON 安全 数据可视化
Elasticsearch(es)在Windows系统上的安装与部署(含Kibana)
Kibana 是 Elastic Stack(原 ELK Stack)中的核心数据可视化工具,主要与 Elasticsearch 配合使用,提供强大的数据探索、分析和展示功能。elasticsearch安装在windows上一般是zip文件,解压到对应目录。文件,elasticsearch8.x以上版本是自动开启安全认证的。kibana安装在windows上一般是zip文件,解压到对应目录。elasticsearch的默认端口是9200,访问。默认用户是elastic,密码需要重置。
6894 0
|
Linux 虚拟化 Docker
Linux服务器部署docker windows
在当今软件开发中,Docker成为流行的虚拟化技术,支持在Linux服务器上运行Windows容器。流程包括:1) 安装Docker;2) 配置支持Windows容器;3) 获取Windows镜像;4) 运行Windows容器;5) 验证容器状态。通过这些步骤,你可以在Linux环境中顺利部署和管理Windows应用,提高开发和运维效率。
2780 1
|
安全 Windows
【Azure Cloud Service】在Windows系统中抓取网络包 ( 不需要另外安全抓包工具)
通常,在生产环境中,为了保证系统环境的安全和纯粹,是不建议安装其它软件或排查工具(如果可以安装,也是需要走审批流程)。 本文将介绍一种,不用安装Wireshark / tcpdump 等工具,使用Windows系统自带的 netsh trace 命令来获取网络包的步骤
599 32
|
Ubuntu 网络协议 Linux
快速部署WSL(Windows Subsystem for Linux)
WSL提供了一种轻量级的方法,使开发者能够在Windows上无缝运行Linux环境。通过本文介绍的步骤,可以快速安装、配置和使用WSL,以满足开发和测试的需求。
3538 8
|
C# Windows
【Azure App Service】在App Service for Windows上验证能占用的内存最大值
根据以上测验,当使用App Service内存没有达到预期的值,且应用异常日志出现OutOfMemory时,就需要检查Platform的设置是否位64bit。
430 11
|
Windows
Windows操作系统部署安装Kerberos客户端
详细介绍了在Windows操作系统上部署安装Kerberos客户端的完整过程,包括下载安装包、安装步骤、自定义安装路径、修改环境变量、配置hosts文件和Kerberos配置文件,以及安装后的验证步骤。
3137 3
Windows操作系统部署安装Kerberos客户端
|
Java 应用服务中间件 开发工具
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
339 2
|
Java 应用服务中间件 Windows
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
306 2