最近项目中用到window服务程序,以前没接触过,比较陌生,花了两 天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作不成功,可能是开发环境或项目配置的不同,这里把自己成功制作 的方式贴出来,一方面留给自己,一方面也希望能给遇到同样问题绝望中不能自拔、以致失去灵魂的路人甲,路人乙一还魂丹 . . .
ide :win2003 vs2008 sql2005
一、创建window服务项目
首先我们建一个window服务项目 :解决方案(右击)——> 增加 ——> 新建项目——>项目类型选择windows——>模板选择windows服务 ,如图:
二、编写window服务程序
创建后会生成两个文件 program.cs 和 service1.cs ,其中 program.cs 这个文件不用动,里面已自动生成好了。我们在service1.cs里增加所要的操作,里面有两个重写方法 onstart 和 onstop ,onstart 方法表示服务启动的操作,onstop 表示服务停止的操作,下面写了一个简单示例 :当服务启动后,调用远程一个webservice的hello函数,并把返回的值写入到一个文件中。code如下:
code highlighting produced by actipro codehighlighter (freeware)
http://www.codehighlighter.com/
-->/// <summary>
/// 服务启动的操作
/// </summary>
/// <param name="args"></param>
protected override void onstart(string[] args)
{
starthello();
}
/// <summary>
/// 服务停止的操作
/// </summary>
protected override void onstop()
{
try
{
threadhello.abort();
flag = false;
system.diagnostics.trace.write("线程停止");
}
catch (exception ex)
{
system.diagnostics.trace.write(ex.message);
}
}
private thread threadhello;
private void starthello()
{
try
{
// 标准形式
//threadstart newthreadstart = new threadstart(voidname);
//thread newthead = new thread(newthreadstart);
//newthead.start();
threadhello = new thread(new threadstart(hello));
threadhello.start();
system.diagnostics.trace.write("线程任务开始");
}
catch (exception ex)
{
system.diagnostics.trace.write(ex.message);
throw ex;
}
}
private void hello()
{
while (flag)
{
localhost.advservice la = new windowsservice1.localhost.advservice();
try
{
string helloname = la.hello("andy"); // 调用远程webservice中的方法
writeinlog(helloname, false); // 把调用返回的数据写入到文件中
}
catch (exception ex)
{
system.diagnostics.trace.write(ex.message);
throw ex;
}
thread.sleep(5000);
}
}
/// <summary>
/// 写入文件操作
/// </summary>
/// <param name="msg">写入内容</param>
/// <param name="isautodelete">是否删除</param>
private void writeinlog(string msg, bool isautodelete)
{
try
{
string logfilename = @"e:/sample/pg_sample/log.txt"; // 文件路径
fileinfo fileinfo = new fileinfo(logfilename);
if (isautodelete)
{
if (fileinfo.exists && fileinfo.length >= 1024)
{
fileinfo.delete();
}
}
using (filestream fs = fileinfo.openwrite())
{
streamwriter sw = new streamwriter(fs);
sw.basestream.seek(0, seekorigin.end);
sw.writeline("=====================================");
sw.write("添加日期为:" + datetime.now.tostring() + "/r/n");
sw.write("日志内容为:" + msg + "/r/n");
sw.writeline("=====================================");
sw.flush();
sw.close();
}
}
catch (exception ex)
{
ex.tostring();
}
}
例子很简单,方便理解,上面通过线程,每5秒执行一次操作,到这里,我们的服务以及服务实现的功能就已经写好了,下面怎么让客户端安装我们的服务呢?这里 才是我写这篇文章的目的!先要增加一个安装程序类,切换到视图窗口,右击——>增加安装程序,便会增加一个程序安装类文件 projectinstaller.cs,如图:
这里serviceprocessinstaller1 和 serviceinstaller1 有几个重要属性要设置,serviceinstaller1 中的starttype要设置成automatic,表示随机启动,servicename表示服务名称,description 表示服务的描述, displayname 表示显示名称。serviceprocessinstaller1 中的account要设置成localsystem,表示本地系统帐号
window服务的安装有两个方式:
一、命令安装
由于我们是安装服务,就不需要用户桌面和程序菜单了,直接应用程序文件夹(右击)——> 增加 ——> 项目输出 入图 :
上面有两点需要注意 ,一 项目选择中选择要安装的服务, 二 项目选择下面要选择主输出,选择好后确定,这一步增加了安装程序的文件夹,下一步就是给这个安装程序增加操作,这里我们增加两个基本操作,一个是安装,一 个是卸载。安装项目(右击) ——> 视图 ——> 自定义操作 如图
上面可以看到有安装,提交,回滚,卸载等操作,我们先增加安装操作,安装(右击)——> 增加自定义操作,会弹出一个对话 如图:
选择应用程序文件夹,并选中之前增加的主输出项,确定,这样这个安装程序就增加了安装的操作,同样按照这样的方式增加卸载操作,卸载与安装唯一不同的是需要设置一个命令参数,不可少,如图:
这里 arguments 里输入 /u 表示卸载命令相当于 installutil.exe /u 服务路径 , 到这里 ,我们的安装程序就已经制作好了,生成安装程序项目,将会生成 setup.exe 和 setup.msi 安装文件,拷贝到客户端,点击setup.exe 就像安装qq一样安装我们的服务,实际上比qq好多了,qq还有广告,我们可是纯绿色的!