文章大部分内容转自:http://www.cnblogs.com/greatandforever/archive/2008/10/14/1310504.html;和:http://www.cnblogs.com/xujie/p/5695673.html;部分是我自己后来的一些理解添加进去的。

正文:在网上看了一些示例,大部分都言过其实,把过程搞得太过复杂,老是需要去研究如何利用InstallUtil.exe及其参数。事实上,既然要安装.net下制作的windows服务,肯定首先得在目标机器上安装有.net框架。因此,InstallUtil.exe也一定已经存在目标机器上了,因而利用微软的傻瓜式操作就能很好地解决windows服务安装和卸载的问题。

过一段时间估计还要狠狠地利用windows服务来完成一些功能,为了加深印象,又回过头弄了一个名叫HelloWorldService的windows服务,用最简单的demo来完成所有的操作。这个服务的功能,仅仅是在它启动的时候创建一个HelloWorld.txt文件,里边写上Hello World!这几个简单的字母而已。

1、新建windows服务项目,我这里选择的是Framework4.0,没有选择高版本是为了防止在服务在一些低版本系统上无法正常运行。

2、新建的Windows 服务项目如图右侧所示,双击Service1.cs,出现左侧Windows 服务的 设计界面,对左侧界面右击,点击 添加安装程序(用于添加Windows 服务的安装程序)。

这里貌似不需要修改Service1.cs设计界面的属性列表中的ServiceName值(该值默认是Service1),这个值会被添加的安装程序(ProjectInstaller.cs)中设计界面的serviceInstaller1的属性列表中的ServiceName的值覆盖/替代,故更改serviceInstaller1中的ServiceName值就可以了,该值就是sc delete XXX 的XXX的值。

3、添加安装程序后项目中会生成带有默认配置的ProjectInstaller.cs文件,如图右侧(看图标样子应该也是个服务文件,和Service1.cs对应),左侧是该文件(服务)的设计界面

4、新建完安装程序后,需要给ProjectInstaller.cs中默认的serviceInstaller1和serviceProcessInstaller1做一些基本的属性设置。如下图:

4.1、serviceInstaller1的配置:

图1:

ServiceInstaller安装一个类,该类扩展 ServiceBase 来实现服务。在安装服务应用程序时由安装实用工具调用该类。在这里主要修改其StartType属性。此值指定了服务的启动模式。

Automatic 指示服务在系统启动时将由(或已由)操作系统启动。如果某个自动启动的服务依赖于某个手动启动的服务,则手动启动的服务也会在系统启动时自动启动。 
Disabled 指示禁用该服务,以便它无法由用户或应用程序启动。 
Manual 指示服务只由用户(使用“服务控制管理器”)或应用程序手动启动。

图2:

这里作下解释(解释以这里的为准,图片上的描述及名字的解释有些不准):上图中的Description是系统(Windows)服务中对应的服务的描述,而DisplayName该服务的名称,而ServiceName则是

Windows 任务管理器的服务页中的对应项的名称;这三个名字都可以用中文,但是ServiceName最好用英文(这个值就是 sc delete XXX的XXX对应的值)

4.2、serviceProcessInstaller1的配置:

图1:

ServiceProcessInstall安装一个可执行文件,该文件包含扩展 ServiceBase 的类。该类由安装实用工具(如 InstallUtil.exe)在安装服务应用程序时调用。在这里主要是修改其Account属性。

ServiceAccount指定服务的安全上下文,安全上下文定义其登录类型。

LocalService    充当本地计算机上非特权用户的帐户,该帐户将匿名凭据提供给所有远程服务器。 
LocalSystem    服务控制管理员使用的帐户,它具有本地计算机上的许多权限并作为网络上的计算机。 
NetworkService    提供广泛的本地特权的帐户,该帐户将计算机的凭据提供给所有远程服务器。 
User    由网络上特定的用户定义的帐户。如果为 ServiceProcessInstaller.Account 成员指定 User,则会使系统在安装服务时提示输

入有效的用户名和密码,除非您为 ServiceProcessInstaller 实例的 Username 和 Password 这两个属性设置值。

图2:

这里也作下解释:设置Account为LocalSystem就相当于在启动该服务时是以管理员权限来启动的。如果上图的Account不设置为LocalSystem而是LocalService可能启动服务会出现以下错误:

想知道原因可以在系统的”事件查看器“中的”应用程序“选项中查看具体的错误信息,如下图:

上图的错误原因是是由于服务对文件系统的操作权限问题所引起的,将serviceProcessInstaller1中的Account由LocalService改成LocalSystem就行了。

5、以上工作完成,安装程序配置完毕,接下来添加应用程序配置文件(如果有需要的话,很多服务项目默认有一个App.config文件的一般是不需要添加),如图:

6、编写windows服务主代码:

 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; namespace OrganizClientSocketService
{
public partial class Service1 : ServiceBase
{
private MainService _mainServ;
public Service1()
{
InitializeComponent();
} // 开启服务要执行的代码
protected override void OnStart(string[] args)
{
_mainServ = new MainService();
_mainServ.Start(); // 开启服务
} // 停止服务要执行的代码
protected override void OnStop()
{
_mainServ.Stop(); // 停止服务
_mainServ = null; // 释放服务资源
}
}
}

7、编译生成Windows 服务程序。

8、上面的Windows 服务项目编译生成的都是 安装包 最终要安装/卸载的对象;接下来就添加一个安装项目用来安装上面的服务,如图:

9、添加工程后,在默认的 视图界面(可通过右击安装项目->视图->文件系统; 打开此视图界面) 右键点击”应用程序文件夹“,选择”添加“->”项目输出“;(这部分也可以参照VS如何添加一个安装项目之类的文章)

在弹出的窗口中选择“主输出”(记得选中项目),点击“确定”。

注意:上面的选择里还有个配置可选,可选项有如图:

如果不选则默认是 (活动),它和需要打包的项目的状态是一致的,如果待打包的项目当前是Debug的,则(活动)代表 Debug Any CPU;

如果你的待打包项目的Release和Debug是不同的,则最好手动选中Debug还是Release(比如待打包项目的Debug是测试用的窗体程序,而Release则是真正要发布的Windows服务程序,这时候最好手动选择)

10、上面的步骤定义了最后在应用程序文件夹中包含的内容。下面来定义其他方面的内容(设置安装程序执行的同时安装服务到系统服务列表中,很重要)

在项目上点右键,选择 视图->自定义操作:

出来如下的界面,然后在”自定义操作“上点右键,选择”添加自定义操作“:

在弹出的窗口中双击”应用程序文件夹“:

然后选择”主输出来自HelloWorldService(活动)“(这部分要根据自己的程序进行相应的更改),点击”确定“:

选择之后会发现所有的操作下边都添加了刚才选定的项,如下图。做到这一步,就能使安装程序卸载时不仅把程序卸载下来,也能把服务卸载下来(安装的同时真正意义上的安装服务)。

11、接下来在安装项目上点右键,选择”生成“,就能使安装程序正常发布了,成功后会生成两个文件(这里貌似只需要 .msi的文件就可以安装了setup.exe不知道有什么用)。

// 这句话可不看:安装成功后根据你的Windows 服务项目中服务安装程序的配置决定是否需要手动启动服务。

重要提示:如果想要windows服务安装后立刻主动启动可以在Windows Service的ProjectInstaller.cs(添加安装程序)中增加下面的代码:

///// <summary>
///// 修改Visual Studio 中 Windows Service的ProjectInstaller.cs中的代码
///// 重写安装完成后函数(只功能都已经安装完成,而不是安装窗体已经关闭)
///// 实现安装完成后自动启动已安装的程序或启动服务(可能需要管理员权限才有用),看下怎样才能让安装程序必须有管理员权限。(或许可以通过C#本身的代码实现开启服务,而不一定要管理员权限)
///// </summary>
//protected override void OnAfterInstall(IDictionary savedState)
//{
// base.OnAfterInstall(savedState);
// MessageBox.Show("是安装完成后才出现的吗?"); // 这个可以执行一个 .bat(net start XXX)来开启Windows服务,不过需要管理员权限;
//}

创建、设置和安装Windows服务的更多相关文章

  1. C#创建、设置和安装Windows服务

    文章大部分内容转自:http://www.cnblogs.com/greatandforever/archive/2008/10/14/1310504.html:和:http://www.cnblog ...

  2. 如何创建一个标准的Windows服务

    出处:http://www.cnblogs.com/wuhuacong/archive/2009/02/11/1381428.html 如何创建一个标准的Windows服务 在很多时候,我们需要一个定 ...

  3. mysql下载和安装Windows服务

    一.下载mysql:https://dev.mysql.com/downloads/mysql/,解压拷贝到D:\software\mysql-8.0.13-winx64 二.在D:\software ...

  4. c# 安装windows服务

    C# windows服务: 第一种 :通过cmd命令安装.卸载.启动和停止Windows Service(InstallUtil.exe) 步骤: 1.运行--〉cmd:打开cmd命令框 2.在命令行 ...

  5. 安装windows服务批处理代码

    批处理是DOS时代比较常用的方法之一,目前来说也是一种高效的方法,复制代码到文本文件中,保存并修改文件扩展名为“*.bat”. 安装windows服务批处理代码如下: @echo off set fi ...

  6. 无法从命令行或调试器启动服务,必须首先安装Windows服务(使用installutil.exe),然后用ServerExplorer、Windows服务器管理工具或NET START命令启动它

    无法从命令行或调试器启动服务,必须首先安装Windows服务(使用installutil.exe),然后用ServerExplorer.Windows服务器管理工具或NET START命令启动它 1. ...

  7. .net安装windows服务配置文件config

    .net安装windows服务 : 在windows服务的项目(WindowsService1)代码文件中有一个app.config 配置文件,可以通过此文件进行时间等的更改而无需重新生成项目:那我们 ...

  8. .net安装windows服务和生产webservice

    安装windows服务 1.打开cmd对话框. 2.输入 cd WINDOWS\Microsoft.NET\Framework64\v2.0.50727\ 3.回车 4.输入InstallUtil.e ...

  9. TopSelf安装Windows服务提示:执行未经授权的操作。。

    在一个项目中用到了八九个服务,服务的执行时间也是五花八门,有的年末执行一次,有的月中执行一次,有的月末最后一天执行一次,有的月初连续执行5天, 有的每天晚上执行,...还好各个服务并没有严格的关联关系 ...

随机推荐

  1. 深入浅出多线程——ReentrantLock (一)

    ReentrantLock是一个排它重入锁,与synchronized关键字语意类似,但比其功能更为强大.该类位于java.util.concurrent.locks包下,是Lock接口的实现类.基本 ...

  2. 分布式缓存之Ehcache与terracotta - Terracotta服务器概念篇

    1.介绍 Terracotta服务器为Terracotta产品提供分布式数据平台.Terracotta服务器集群被称为Terracotta服务器阵列(TSA).Terracotta服务器阵列可以从单个 ...

  3. 74、django之ajax补充

    之前的ajax使用都是依据jquery来使用的,本篇会先分析ajax的原生的js代码实现,还有jsonp的介绍,与OMR的一些遗漏补充. 本篇导航: js实现的ajax 同源策略与Jsonp 一.js ...

  4. ionic3中 ion-datetime 全屏可点击问题解决方案

    废话不多说,能进来的都应该知道是个什么情况.我也是在网上找了一段时间,才在git上ionic官方团队的Issues中找到了问题解决方法. 第一,给外围包上一层ion-item,但是这有个问题,就是会让 ...

  5. Spring-MVC理解之一:应用上下文webApplicationContext

    一.先说ServletContext javaee标准规定了,servlet容器需要在应用项目启动时,给应用项目初始化一个ServletContext作为公共环境容器存放公共信息.ServletCon ...

  6. Linux 链接详解----动态链接库

    静态库的缺点: 库函数被包含在每一个运行的进程中,会造成主存的浪费. 目标文件的size过大 每次更新一个模块都需要重新编译,更新困难,使用不方便. 动态库: 是一个目标文件,包含代码和数据,它可以在 ...

  7. mysql主从复制笔记

    一:测试环境介绍 主从复制测试环境是ubuntu+mysql5.7,master服务器ip是192.168.71.135,slave服务器ip是192.168.71.137,ubuntu环境是从一台已 ...

  8. Oracle的导入导出 DMP 文件

    普通 导入: 将数据库完全导入,用户名userName 密码PassWord导入文件位置 E:\work\dmp\xxxxx.dmp (注意:导入的用户必须要跟导出时候的用户一致) imp userN ...

  9. KafkaManager中Group下不显示对应Topic的解决方案

    一.软件版本 Kafka:0.8.2.1 KafkaManager:1.2.9.10 二.问题现象 点击Consumer下某个组,显示如下图所示的异常,查看KafkaManager的Applicati ...

  10. HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:给你一个长度n的数列,初始都为0.有三种操作,第一种给第k个位置的数加d.另外一种是查询区间 ...