C#实现Windows后台服务实例浅析

C#实现Windows后台服务实例之前要明白的一些概念:所谓Windows后台服务,即后台自动运行的程序,一般随操作系统启动而启动,在我的 电脑 服务后应用程序 服务里面能看到当前电脑的服务.一般而言,程序上用VC、C++写Windows服务,但是我对这些语言不是很熟,一般编程用C#较多,所以就用C#语言 写了一个Windows服务.

C#实现Windows后台服务实例其实需求是这样的,做那个报价系统的时候加入了发短信的功能,订单处理完即将发货的时候要发送短信都客户手机 上,公司内部员工处理订单超时要自动发短信,群发产品促销信息到客户手机上等,还有定时发送短信的需求,所以最后面决定把发短信的模块独立出来,以后还有 什么功能方便一起调用,而最终选择了采用Windows后台服务.

C#实现Windows后台服务实例其实Windows服务并不好做到通用,它并不能在用户的界面显示一些什么信息等,它只是在后台默默的处理一些 事情,起着辅助的作用.那如何实现发送段信通用调用的接口呢?它们之间的信息又是如何来交互呢?数据库!对,就是它存储数据信息的.而数据库都能很方便的 访问操作.把发送短信的后台服务定时去访问一个数据库,而另外任何要发送短信的地方也访问数据库,并插入一条要发送的短信到表里面,稍后Windows后 台服务访问该表将此短信发送出去.这可能是一个比较蠢的方法,但实现起来较简单.

C#实现Windows后台服务实例首先,由于它是要安装的,所以它运行的时候就需要一个安装类Installer将服务安装到计算机,新建一个后 台服务安装类继承自Installer,安装初始化的时候是以容器进行安装的,所以还要建立ServiceProcessInstaller和 ServiceInstaller服务信息组件添加到容器安装,在Installer类增加如下代码:

 
 
  1. private  System.ComponentModel.IContainer components =  null ;  
  2. private  System.ServiceProcess.ServiceProcessInstaller spInstaller;  
  3. private  System.ServiceProcess.ServiceInstaller sInstaller;  
  4. private   void  InitializeComponent()  
  5. {  
  6. components =  new  System.ComponentModel.Container();  
  7.  
  8. // 创建ServiceProcessInstaller对象和ServiceInstaller对象  
  9. this .spInstaller =  new  System.ServiceProcess.
  10. ServiceProcessInstaller();  
  11. this .sInstaller =  new  System.ServiceProcess.ServiceInstaller();  
  12.  
  13. // 设定ServiceProcessInstaller对象的帐号、用户名和密码等信息  
  14. this .spInstaller.Account = System.ServiceProcess.
  15. ServiceAccount.LocalSystem;  
  16. this .spInstaller.Username =  null ;  
  17. this .spInstaller.Password =  null ;  
  18.  
  19. // 设定服务名称  
  20. this .sInstaller.ServiceName =  "SendMessage" ;  
  21. sInstaller.DisplayName =  "发送短信服务" ;  
  22. sInstaller.Description =  "一个定时发送短信的服务" ;  
  23.  
  24. // 设定服务的启动方式  
  25. this .sInstaller.StartType = System.ServiceProcess.
  26. ServiceStartMode.Automatic;  
  27.  
  28. this .Installers.AddRange( new  System.Configuration.
  29. Install.Installer[] {  this .spInstaller,  this .sInstaller });  

C#实现Windows后台服务实例再添加一个服务类继承自ServiceBase,我们可以重写基类的OnStart、OnPause、 OnStop、OnContinue等方法来实现我们需要的功能并设置指定一些属性.由于是定事发送短信的服务,自然少不了Windows记时器,在 OnStart事件里我们写入服务日志,并初始化记时器.

 
 
  1. private  System.Timers.Timer time;  
  2. private   static   readonly   string  CurrentPath = 
  3. Application.StartupPath +  "//" ;  
  4. protected   override   void  OnStart( string [] args)  
  5. {  
  6. string  path = CurrentPath +  "Log//start-stop.log" ;  
  7. FileStream fs =  new  FileStream(path, FileMode.
  8. Append, FileAccess.Write);  
  9. StreamWriter sw =  new  StreamWriter(fs);  
  10. sw.WriteLine( "The Service is Starting On "  + 
  11. DateTime.Now.ToString());  
  12. sw.Flush();  
  13. sw.Close();  
  14. fs.Close();  
  15.  
  16. time =  new  System.Timers.Timer(1000 * Convert.
  17. ToInt32(GetSettings( "TimeSpan" )));  
  18. time.Enabled =  true ;  
  19. time.Elapsed +=  this .TimeOut;  
  20. time.Start();  

C#实现Windows后台服务实例实例化记时器类启动后,将在指定时间间隔触发Elapsed指定事件,如上GetSettings为读取我 App.config文件里一个配置节点(值为30)的方法,所以上面将会每隔30秒调用TimeOut方法.而改方法就是我们发短信的具体操作.代码如 下:

 
 
  1. private   void  TimeOut( object  sender, EventArgs e)  
  2. {  
  3. try  
  4. {  
  5. if  (GetSettings( "Enabled" ).ToLower() ==  "true" )  
  6. {  
  7. SqlConnection con =  new  SqlConnection(GetSettings( "ConnString" ));  
  8. SqlCommand cmd =  new  SqlCommand( "select [sysid],
  9. [admin_inner_code],[user_inner_code],[phone],
  10. [message],[sendtime] from [tbl_note_outbox]" , con);  
  11. con.Open();  
  12. SqlDataReader rdr = cmd.ExecuteReader();  
  13. while  (rdr.Read())  
  14. {  
  15. string  phone = rdr[ "phone" ].ToString();  
  16. string  message = rdr[ "message" ].ToString();  
  17. string  sendtime = rdr[ "sendtime" ].ToString();  
  18. System.Text.Encoding encoder = System.Text.Encoding.GetEncoding( "GB2312" );  
  19. string  url =  string .Format( "http://211.155.23.205/
  20. isapi.dll?SendSms&AgentID={0}&PassWord={1}&phone={2}&msg={3}&sendtime={4}"
  21. GetSettings( "AgentID" ), GetSettings( "PassWord" ), 
  22. phone,System.Web.HttpUtility.UrlEncode( message,encoder), sendtime);  
  23. System.Net.WebClient wClient =  new  System.Net.WebClient();  
  24. string  msg = System.Text.Encoding.Default.GetString(wClient.DownloadData(url));  
  25. wClient.Dispose();  
  26.  
  27. //删除已经发送成功的,并保存发送记录  
  28. if  (msg ==  "发送成功" )  
  29. {  
  30. DateTime dtsend = sendtime ==  "0"  ? DateTime.Now : 
  31. DateTime.ParseExact(sendtime,  "yyyyMMddHHmmss"null );  
  32. string  sql =  string .Format( "delete from 
  33. [tbl_note_outbox] where [sysid]={0} INSERT INTO [tbl_note_log] 
  34. ([admin_inner_code],[user_inner_code],[status],[phone],
  35. [message],[sendtime]) VALUES('{1}','{2}','{3}','{4}','{5}','{6}')" ,
  36.  rdr[ "sysid" ], rdr[ "admin_inner_code" ], rdr[ "user_inner_code" ],
  37.  msg, phone, message, dtsend);  
  38. SqlConnection conn =  new  SqlConnection(GetSettings( "ConnString" ));  
  39. SqlCommand delete =  new  SqlCommand(sql, conn);  
  40. conn.Open();  
  41. delete.ExecuteNonQuery();  
  42. conn.Close();  
  43. delete.Dispose();  
  44. }  
  45.  
  46. }  
  47. rdr.Close();  
  48. con.Close();  
  49. cmd.Dispose();  
  50. }  
  51. }  
  52. catch  (Exception ex)  
  53. {  
  54. string  errorPath = CurrentPath +  "Log//error.log" ;  
  55. if  (!File.Exists(errorPath))  
  56. {  
  57. FileStream create = File.Create(errorPath);  
  58. create.Close();  
  59. }  
  60. FileStream fs =  new  FileStream(errorPath, 
  61. FileMode.Append, FileAccess.Write);  
  62. StreamWriter sw =  new  StreamWriter(fs);  
  63. sw.WriteLine( "Exception: "  +ex.Message+ " --" +
  64.  DateTime.Now.ToString());  
  65. sw.Flush();  
  66. sw.Close();  
  67. fs.Close();  
  68. }  
  69.  

C#实现Windows后台服务实例上面我们使用try、catch访问数据库,并记录错误异常信息. 发送短信是使用发送一个Web请求发送出去的,要注意请求url字符串的编码类型,要与请求页面编码一致,不然会出现乱码.上面我们请求的是智网通集团短 信(网址:http://www.09168.net/)的Web接口,通过访问他的网站来实现发短信,当然还要传递一些用户名、密码、手机号码和要发送 的短信息等参数.他的收费平均大概为7分/条的样子,其实我原本不想用发送Web请求的这样方式来发送短信的,它本身提供了调用它发送短信的DLL,而且 还有vc、delphi调用的Demo,但是没有用C#调用的例子,我刚开始试着用非托管动态链接库他提供的DLL,不知方法调用那里出错了一直都没能成 功发送出短信,所以后来就用了他的Web方式接口了.他页面直接返回发送短信的状态信息.返回发送成功则短信发送成功,成功后我再将此条信息从要发送短信 表里删除并保存在发送记录表里面,以备日后方便查询.其实登陆他的官网进入后台也能方便的查询,如下图.

保存在发送记录表里面  

C#实现Windows后台服务实例发送短信服务的代码基本上搞定了,就看怎么在服务器上安装部署了.C#写的Windows后台服务不能直接安 装,需要借助.NET Framework里面的InstallUtil.exe安装工具安装,我们可以做成一个执行CMD命令的文件BAT文件来安装启动它,命令如下:

 
 
  1. %windir%/Microsoft.NET/  
  2. Framework/v2.0.50727/  
  3. InstallUtil.exe %CD%/  
  4. SendMessage.exe  
  5. net start SendMessage 

安装启动  

安装完成以后,我们可以在我的电脑管理服务里面看到才安装上的后台服务.

后台服务  

经测试,采用定时访问数据库发送短信的服务并不是很耗资源,刚启动的时候只占用内存为7、8M左右,经过在服务器上连续运行几天不关闭占用的内存也 只升到15M左右,运行比较稳定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值