zoukankan      html  css  js  c++  java
  • 使用Visual Studio 2015 Community 开发windows服务

      昨天研究在.NET下开发Windows服务程序,期间遇到一些小问题,这里仅将自己的开发过程和需要注意的地方写下和广大网友分享……

       1、基础

        Windows服务是指系统启动时能够自己运行的程序。Windows服务可以在没有交互界面的情况下在后台进行业务的处理。

      .NET下开发Windows服务需要几个基本的类,它们在程序集System.ServiceProcess.dll和System.Configuration.Install.dll中,分别是:ServiceBase、ServiceInstaller、ServiceProcessInstaller、Installer,这几个类是开发一个最简单的Windows服务所必须的。

      2、使用Visual Studio 2015 Commnuity创建Windows服务项目

        

      在Classic Desktop(经典桌面程序)中选择Windows Service项目。项目文件结构如下:

      

      双击Service1.cs进入服务设计界面,设置ServiceName属性(该属性在下文中还会提及,请留意),该属性是系统控制Windows服务的标识:

      

      这里我将ServiceName属性设置为Test,大家注意看属性面板的上边,发现这里设置的是ServiceBase类的属性。ServiceBase类是.NET中创建所有Windows服务的基类。在创建新的服务类时,必须从 ServiceBase 派生。

      接下来我们看下Service1.cs文件的代码部分,可以看到里面有个Service1类继承自ServiceBase类,还有两个重写方法,OnStart和OnStop。OnStart中的代码将会在服务启动之后运行,OnStop中的代码在服务停止时运行。除此之外还有OnPause、OnContinue等方法。这是我们编译项目会在binDubug文件夹下生成WindowsService1.exe文件,这个文件就是我们创建的Windows服务。是不是感觉很简单?但是如果你以为Windows服务的创建工作到此为止就结束了,那就错了。不信双击WindowsService1.exe运行试试……

    3、Windows服务的安装

      看到了吧,提示我们想要运行Windows服务要先安装该服务

      

      提示信息中提到了installutil.exe,这里先不说它的用处。我们要想安装刚刚创建的Windows服务,首先要在项目中创建安装文件,如图:

      

      双击刚刚创建的Installer1.cs文件会进入它的设计界面,这里且不管设计界面,我们直接进入代码界面,会看到里面有一个类:Installer1,它继承自

    System.Configuration.Install命名空间下的Installer类,Installer 类是 .NET中所有自定义安装程序的基类。

      首先我们在Installer1的构造函数中定义我们的服务进程安装类(即上文提到的ServiceProcessInstaller)实例和服务安装类(即上文提到的ServiceInstaller)实例

            public Installer1()
            {
                InitializeComponent();
    
                ServiceProcessInstaller spi = new ServiceProcessInstaller();
                spi.Account = ServiceAccount.LocalSystem;//设置服务要运行在什么类型的账号下
    
                //这里可以创建多个ServiceInstaller实例
                ServiceInstaller si = new ServiceInstaller();
                si.ServiceName = "Test";//系统操作服务的标识,要和ServiceBase中设置的ServiceName属性值相同
                si.DisplayName = "测试服务";//展示给用户的服务名,即在控制面板中看到的服务名
                si.Description = "服务的描述信息";
                si.StartType = ServiceStartMode.Manual;//服务的启动方式,这里设置为手动
    
                //最后记得把创建的实例添加到安装列表中
                this.Installers.Add(si);
                this.Installers.Add(spi);
            }
    View Code

      到此,对于安装服务的基本信息已经填写完毕。接下来我们还需要重写基类Installer中的两个方法:

            //注意必须重写Install和Uninstall方法,且在重写方法中必须调用基类对应的方法,否则在安装和卸载服务的过程中会出问题
            //小编就是因为没有调用基类中的方法导致安装和卸载出现问题
            //出此之外还有Commit、Rollback等方法
            public override void Install(IDictionary stateSaver)
            {
                base.Install(stateSaver);
            }
    
            public override void Uninstall(IDictionary savedState)
            {
                base.Uninstall(savedState);
            }    
    View Code

      

      这里大家要注意一点,在Installer1类上使用了特性:RunInstaller(true),如果我们将特性的参数设为false,那么安装工具installutil将会忽略该类,我们在安装服务时就不会安装该类中指定的服务。

      完成上述步骤之后,我们再次编译项目……

      在上文中我们提到了installutil.exe工具,它是用来安装.NET编写的Windows服务的工具,它的路径是C:WindowsMicrosoft.NETFrameworkv4.0.30319InstallUtil.exe。其中v4.0.30319是.NET的版本号,使用不同版本的.NET编写Windows服务要使用对应的installutil.exe来安装。

      我们打开命令行或使用VS自带的命令行工具,这里我们使用VS自带的命令行工具:Developer Command Prompt for VS2015来进行安装工作。

      打开命令行工具,输入:installutil.exe Windows服务程序的路径(这里小编涂去了和个人信息相关的部分)然后回车

      

      如使用系统的命令行工具就需要先跳转到installutil.exe所在的路径或者在命令行中指明它的路径。

      回车之后会发现,Windows服务开始安装了,在然后就会发现安装出现了问题……

      

      对于这个问题的解决方式相当简单,就是以管理员身份运行命令行工具即可(小编却花费了很长的时间才悟出来这个道理)。

      以管理员身份运行命令行,再次执行安装过程,我们可以看到安装过程分为:安装和提交两步。

      安装完成之后,我们可以在控制面板的服务管理器中看到刚刚安装的服务:

      

      安装完成之后我们来启动服务,这里使用命令行来启动,也可以在服务管理器中启动。

      

      大家注意到没有?控制面板服务管理器中显示的服务名称是DisplayName属性指定的名称,而我们启动服务时要使用ServiceName属性指定的服务名,否则会提示我们服务名无效。

      服务的停止使用命令:net stop 服务名称。

      服务的卸载使用installutil /u 服务程序路径来完成。

      至此,在.NET中开发一个简单的Windows服务的工作已经全部完成……

    版权声明

    本文为作者原创,版权归作者雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明原文链接

    如有问题, 请发送邮件和作者联系。

  • 相关阅读:
    「日常训练」Single-use Stones (CFR476D2D)
    「日常训练」Greedy Arkady (CFR476D2C)
    「Haskell 学习」二 类型和函数(上)
    「学习记录」《数值分析》第二章计算实习题(Python语言)
    「日常训练」Alena And The Heater (CFR466D2D)
    Dubbo 消费者
    Dubbo 暴露服务
    Rpc
    git fail to push some refs....
    Spring Cloud (6)config 客户端配置 与GitHub通信
  • 原文地址:https://www.cnblogs.com/Cwj-XFH/p/5129812.html
Copyright © 2011-2022 走看看