windows 服务开发教程

一、 window服务是什么

 

当你单击“开始”,执行“services.msc”命令。就会看见如下窗口。它显示的是当前操作系统中系统自带的服务或者第三方软件安装的服务。服务的状态有名称、描述、启动状态、启动类型等等。你也可以在此窗体中管理相关服务,注意谨慎操作,防止系统错误或软件故障。

clip_image002

在此,为了让大家对后面使用的代码项目有个整体了解。整个专案有如下项目:

1、ServerForm: 一个WinForm程序,为window服务MyService测试而调用(永远只弹出一个,除非之前弹出的ServerForm的关闭)。

2、CreateWSSetup:一个Console程序,为window服务MyService

生成安装和卸载脚本而使用。并且在服务安装包MyServiceSetup中调用。传入参数install标识安装和启动服务,unstall表示停止和卸载服务。

3、MyService: 我们今天的重点,一个Window服务程序。

4、MyServiceSetup:一个Window服务的安装包程序。支持Window服务MyService的安装和启动、停止和卸载。

clip_image004

 

 

二、 Window服务如何开发

 

在这里只从C#.NET开发的角度,来简单介绍Window服务的开发。

1、 新建一个Window服务项目。

clip_image006

 

2、 编写MyService主要代码

MyService类继承微软封装的服务基类ServiceBase

public partial class MyService : ServiceBase

服务启动OnStart(string[] args),你可以选择是否带传入参数来执行服务。

 

// 启动服务

protected override void OnStart(string[] args)

{

// 在此处添加代码以启动服务

timer.Enabled = true;

}

 

服务停止OnStopt()

// 停止服务

protected override void OnStop()

{

// 在此处添加代码以执行停止服务所需的关闭操作。

timer.Enabled = false;

System.Diagnostics.Process[] myproc = System.Diagnostics.Process.GetProcessesByName("ServerForm");

if (myproc != null && myproc.Length > 0)

{

int n = myproc.Length;

for (int i = 0; i < n; i++)

{

myproc[i].Kill();

}

}

}

 

此处为自定义函数,实现定时弹出第三方程序页面。ServerForm是另外一个C#.NET的WinForm程序。我们把它放到

MyService\Bin\Debug下面。

 

// 定时执行

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

{

System.Diagnostics.Process[] myproc = System.Diagnostics.Process.GetProcessesByName("ServerForm");

if (myproc == null || myproc.Length == 0)

{

// 控制程序, 单例执行

System.Diagnostics.Process.Start(AppDomain.CurrentDomain.BaseDirectory + "ServerForm.exe");

}

}

 

最后,我们看下完整的MyService代码

public partial class MyService : ServiceBase

{

private static System.Timers.Timer timer = null;

// 服务构造

public MyService()

{

InitializeComponent();

if (timer == null)

{

timer = new System.Timers.Timer();

timer.Enabled = true;

timer.Interval = 10000; // 10秒

timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);

this.ServiceName = "MyService";

}

}

// 启动服务

protected override void OnStart(string[] args)

{

// 在此处添加代码以启动服务

timer.Enabled = true;

}

// 停止服务

protected override void OnStop()

{

// 在此处添加代码以执行停止服务所需的关闭操作。

timer.Enabled = false;

System.Diagnostics.Process[] myproc = System.Diagnostics.Process.GetProcessesByName("ServerForm");

if (myproc != null && myproc.Length > 0)

{

int n = myproc.Length;

for (int i = 0; i < n; i++)

{

myproc[i].Kill();

}

}

}

// 定时执行

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

{

System.Diagnostics.Process[] myproc = System.Diagnostics.Process.GetProcessesByName("ServerForm");

if (myproc == null || myproc.Length == 0)

{

// 控制程序, 单例执行

System.Diagnostics.Process.Start(AppDomain.CurrentDomain.BaseDirectory + "ServerForm.exe");

}

}

}

配置服务的Install组件。当我们写好一个MyService.cs服务后,它还不能直接安装和注册。我们还需要为它配置Install安装组件,具体操作步骤如下:

步骤1:选中服务MyService.cs,双击鼠标。在VS2008左边区域弹出MyService.cs[设计]*选项卡。

clip_image008

 

步骤2:在“MyService.cs[设计]*选项卡”中,右键鼠标单击选项“添加安装程序”。

clip_image010

在执行“添加安装程序”之后,可以看见项目中多了如下文件和组件。

clip_image012

 

步骤3:设置安装服务的相关属性

1、设置组件serviceInstaller1的主要属性

StartType: AutoMatic自动、Manual手动,Disabled禁止。

ServiceName: 服务系统标识,

在cmd命令中执行sr start/stop/query等等命令时候使用,用来唯一标识一个Window服务。

clip_image014

 

2、设置组件serviceProcessInstaller1的主要属性

Accout:账户类型。LocalService基于本机运行服务、NetworkService基于网络运行服务、LocalSystem本地系统服务、User基于用户认证的服务。

clip_image016

 

3、 设置服务安装后“允许和桌面进行交互”,

需要在ProjectInstaller.cs中添加如下代码。

namespace MyService

{

[RunInstaller(true)]

public partial class ProjectInstaller : Installer

{

public ProjectInstaller()

{

InitializeComponent();

}

protected override void OnAfterInstall(IDictionary savedState)

{

try

{

base.OnAfterInstall(savedState);

// 允许服务桌面交互

System.Management.ManagementObject myService = new System.Management.ManagementObject(string.Format("Win32_Service.Name='{0}'", this.serviceInstaller1.ServiceName));

System.Management.ManagementBaseObject changeMethod = myService.GetMethodParameters("Change");

changeMethod["DesktopInteract"] = true;

System.Management.ManagementBaseObject OutParam = myService.InvokeMethod("Change", changeMethod, null);

}

catch (Exception ex)

{

}

}

}

}

 

三、 Windows服务的安装和卸载

 

注意:在执行安装或卸载服务前,我有把服务需要的相关文件,复制到C:\MyService\下面或其他路径。一旦安装完成后,此目录不能变更,否则不能卸载该服务和服务运行会报错。

方法一:cmd命令方式

单击开始,执行cmd命令。在弹出cmd窗口中安装或卸载服务。

1、 安装服务: sr start为启动服务

基本命令,如下:

%systemroot%\microsoft.net\framework\v2.0.50727\installUtil.exe C:\MyService\MyService.exe

sc start "TaskWS"

步骤1:安装MyServie服务,如下图:

clip_image018

执行安装命令,接着显示安装和注册服务的结果消息,如下图。

clip_image020 

步骤2:如上图,显示结果安装服务成功,接下来我们去服务管理界面,查看服务是否出现。如下图所示。

clip_image022

步骤3:接下来启动MyService服务:执行sc start "MyService"命令。

clip_image024

 

2、卸载服务

sc stop "MyService"

%systemroot%\microsoft.net\framework\v2.0.50727\installUtil.exe /u C:\MyService\MyService.exe

操作步骤,类似安装服务的步骤,略。

 

方法二:bat文件方式:

原理就是方法一,只是把安装和卸载服务的命令放到installWS.bat和unstallWS.bat中。而且为了减少用户自己写脚本,可以开发一个工具CreateWSSetup.exe负责生成制定Window服务的安装和卸载脚本bat文件。

 

方法三:将服务程序打包成安装包

注意:这里我会新建一个安装项目MyServiceSetup和Console项目CreateWSSetup,其中CreateWSSetup的功能主要是根据MyService.exe生成服务的安装脚本和卸载脚本,并且根据传入参数intall执行安装和启动服务,unstall执行停止和卸载服务。

实现原理,选择安装项目,添加项目输出MyService、添加视图中的行为:

安装:添加项目输出CreateWSSetup.exe,参数为install。

卸载:添加项目输出CreateWSSetup.exe,参数为unstall。

步骤1:添加项目输出,添加MyServie和CreateWSSetup项目输出。

clip_image026

步骤2:添加操作行为: 添加安装和卸载的操作行为

clip_image028

添加安装的自定义行为:选择项目输出CreateWSSetup,设置参数install.

clip_image030

接着设置“安装”的属性:Arguments(install,这个是自己定义,根据你写的执行程序而定)和InstallClass(选否,是因为CreateWSSetup.cs不是一个InstallClass)。

clip_image032

添加卸载的自定义行为:选择项目输出CreateWSSetup,设置参数unstall。操作画面和安装的自定义行为相同,这里就不截图了。

步骤3:选中安装项目MyServiceSetup,执行“重新生成”,即可在Bin\Debug下面得到Window服务MyService的安装和卸载的程序包。

 

四、 Window 服务如何调试

 

首先安装好服务,然后剩下的事情就和普通程序调试一样了。

注意安装的路径,应该是程序所在的Bin\Debug\下的服务程序exe文件。

 

五、 Window 服务的使用价值

 

1、 建立定时执行的工作任务。

2、 建立服务器监控程序。

3、 公共的应用程序访问接口。

4、 其他用途。

 

六、 Window服务使用演习

 

clip_image034

MyService服务定时弹出的程序,你也可以自己写一个Form1.exe程序放到服务中。比如查询服务器上的已有服务。或者重启数据库或IIS等等。

clip_image036

 

其他:

1、安装服务:
方法1: (可以安装多个服务实例)
sc create "MyService_PRD" binPath= "H:\Program Files\MyServiceSetup\MyService"
sc start "MyService_PRD"
 ---- 产生服务1: MyService_PRD
--
sc create "MyService_DEV" binPath= "H:\Program Files\MyServiceSetup\MyService"
sc start "MyService_DEV"
 ---- 产生服务2: MyService_DEV
 
方法2: (不能安装多个服务实例)
%systemroot%\microsoft.net\framework\v2.0.50727\installUtil.exe "H:\Program Files\MyServiceSetup\MyService.exe"
sc start "MyService"

2、卸载服务 
方法1:
sc delete  "MyService_PRD"

方法2:
sc stop  "MyService"
%systemroot%\microsoft.net\framework\v2.0.50727\installUtil.exe /u "H:\Program Files\MyServiceSetup\MyService.exe"

 

后记:

改项目已经在Window XP\Window Server 2003中,验证了安装包的正确运行无误。但是在Window Server 2008中,系统会弹出系统警告窗口“服务已经支持与桌面交互,但是系统没有配置允许:服务允许和桌面进行交互”,如果朋友有知道解决办法的不妨告诉我。多谢。

posted @ 2012-04-22 14:46  tiandong  阅读(10084)  评论(55编辑  收藏  举报