C#创建Windows Service程序

6 篇文章 0 订阅
1 篇文章 0 订阅

今天公司有一个需求,就是要求搭建一个即时通讯系统,并且要在开机后就要运行,无人值守就可以服务的那种。刚得知这个需求的时候,其实心里就有了办法了,不就是去网上找一个即时通信平台嘛,不光能满足我们的要求,还有优质的服务。开干。。。。过了一会发现,网上好的平台价格还不便宜,不要钱了,可能也不敢用;于是乎,只能自己干了。是不是扯的有点远哈。

好了,今天可能工作的时间有限了,干不完(我比较慵懒),我就先干一部分吧,把后台运行服务搞起来吧。

一、创建Windows Service

1.首先,创建一个Windows 服务:

2、在解决方案资源管理器内将Service1.cs改为QZTService1.cs(这个名称是我项目里的名称,你的项目就随你了),然后点击“查看代码”图标按钮进入代码编辑器界面,如下图所示:

public partial class QZTService1 : ServiceBase
    {
        public QZTService1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
        }

        protected override void OnStop()
        {
        }
    }

好了,就完了。服务程序里我现在什么都没干,这个要根据自已的需求来添加代码

3.这一步就是添加服务的安装程序,进入“QZTService1”设计界面,在空白位置右击鼠标弹出上下文菜单,选中“添加安装程序”,如下图所示:

完成后,会自动生成两个组件,分别为“serviceInstaller1”及“serviceProcessInstaller1”,如下图所示:

点击“serviceInstaller1”,在“属性”窗体将ServiceName改为QZTService1,Description改为QZT服务,StartType保持为Manual,如下图所示:

点击“serviceProcessInstaller1”,在“属性”窗体将Account由User改为LocalSystem(服务属性系统级别),如下图所示:

生成项目就算是服务程序写完了(其实什么事情也没干。。),但是还不能收工,因为服务程序是不能直接双击打开运行的;所以我们就要写一点代码来控制它的安装或启动。

二、创建安装、启动、停止、卸载服务的Windows窗体

1.在同一个解决方案里新建一个Windows Form项目,名字你就随便取了。将该项目设置为启动项目,并在窗体内添加四个按钮,分别为安装服务、启动服务、停止服务及卸载服务,我这里用的是一个MenuStrip,和两个Button,如下图所示:

2.接一下就是控制代码了,首先要操作后台服务,必须引入两个类,分别为:“System.ServiceProcess”及“System.Configuration.Install”。

3.代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Data;
using System.Drawing;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MHmlg.QZT.Manage.IM
{
    public partial class Form1 : Form
    {
        string serviceFilePath = $"{Application.StartupPath}\\Service\\QZTService1.exe";
        string serviceName = "QZTService1";
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.VisibleChanged += Form1_VisibleChanged;
        }

        #region Windows服务,安装及启动操作
        //事件:安装服务
        private void 安装ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.IsServiceExisted(serviceName)) this.UninstallService(serviceName);
                this.InstallService(serviceFilePath);
            }
            catch { }
        }
        //事件:卸载服务
        private void 卸载ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.IsServiceExisted(serviceName))
                {
                    this.ServiceStop(serviceName);
                    this.UninstallService(serviceFilePath);
                }
            }
            catch { }
        }

        //事件:启动服务
        private void button1_Click(object sender, EventArgs e)
        {
            if (this.IsServiceExisted(serviceName)) this.ServiceStart(serviceName);
        }

        //事件:停止服务
        private void button2_Click(object sender, EventArgs e)
        {
            if (this.IsServiceExisted(serviceName)) this.ServiceStop(serviceName);
        }

        //判断服务是否存在
        private bool IsServiceExisted(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController sc in services)
            {
                if (sc.ServiceName.ToLower() == serviceName.ToLower())
                {
                    return true;
                }
            }
            return false;
        }

        //安装服务
        private void InstallService(string serviceFilePath)
        {
            using (AssemblyInstaller installer = new AssemblyInstaller())
            {
                installer.UseNewContext = true;
                installer.Path = serviceFilePath;
                IDictionary savedState = new Hashtable();
                installer.Install(savedState);
                installer.Commit(savedState);
            }
        }

        //卸载服务
        private void UninstallService(string serviceFilePath)
        {
            using (AssemblyInstaller installer = new AssemblyInstaller())
            {
                installer.UseNewContext = true;
                installer.Path = serviceFilePath;
                installer.Uninstall(null);
            }
        }
        //启动服务
        private void ServiceStart(string serviceName)
        {
            using (ServiceController control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Stopped)
                {
                    control.Start();
                }
            }
        }

        //停止服务
        private void ServiceStop(string serviceName)
        {
            using (ServiceController control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Running)
                {
                    control.Stop();
                }
            }
        } 
        #endregion
    }
}

打完收工,这个就是创建服务的基本方法,记得运行时要以管理身份运行。如果求调试的话,将服务附加进程到需要调试的项目里面即可。

三、应用程序与Windows服务通信

在应用程序或其他服务中,可以与Windows服务通讯,包括:

  •          管理Windows服务的生命期,即开启、停止、暂停和重启服务;
  •          获得Windows服务的属性和状态;
  •          获得特定计算机上的服务列表;
  •          向特定的服务发送命令。

        这些操作是通过ServiceController 类完成的。ServiceController是一个可视化控件,可以在工具箱中找到。

        比较有意思的是ServiceController 中ExecuteCommand这个方法,调用这个方法,可以向Windows服务发送命令,指挥Windows服务的一些操作。例如,在Windows服务的入口类中有一个复写OnCustomCommand()的方法:

         /// <summary>

         /// 执行用户自定义消息

         /// </summary>

         /// <param name="command">消息编号</param>

         protected override void OnCustomCommand( int command )

         {
              try

              {
                   switch( command )

                   {
                       case 1: // 业务操作
                            doBusiness1();
                            break;
                       case 2: //业务操作
                            doBusiness2();
                            break;
                       default:
                            ……

                            break;
                   }
              }
              catch( Exception ex )
              {

                   // 错误信息
                   string strErrorMsg = string.Format("异常:{0}/n", ex.Message );
                   // 写日志
                   TLineEventLog.DoWriteEventLog( strErrorMsg, EventType.Error );
                   // 给管理员发邮件                   CMail.SendMail(PropertyManager.strMailFromAddress,PropertyManager.strMailAdminAddress,"","异常信息提示",strErrorMsg );
                   // 写Trace
                   Trace.WriteLine( strErrorMsg );
              }
         }

        在另外一个应用程序中通过ServiceController的ExecuteCommand()方法向这个Windows服务发送命令:

            myController.ExecuteCommand(2);

        Windows服务将执行业务方法:doBusiness2();

        应该承认,利用ServiceController与Windows服务通讯的功能目前还十分薄弱。通过ExecuteCommand只能与Windows服务进行简单而有限的通讯。

        笔者在实际的应用中,分别用一个命令行程序、一个控制台程序和一个Webservice和Windows服务进行通讯,启动、停止服务,或通过ExecuteCommand控制服务的行为。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值