惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Vulnerabilities – Threatpost
L
LINUX DO - 热门话题
H
Hacker News: Front Page
Hacker News - Newest:
Hacker News - Newest: "LLM"
L
Lohrmann on Cybersecurity
Cisco Talos Blog
Cisco Talos Blog
O
OpenAI News
S
Securelist
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
H
Heimdal Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
Microsoft Azure Blog
Microsoft Azure Blog
MyScale Blog
MyScale Blog
Webroot Blog
Webroot Blog
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
Latest news
Latest news
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic
D
Docker
D
DataBreaches.Net
A
About on SuperTechFans
T
Tor Project blog
V
V2EX
G
Google Developers Blog
博客园 - Franky
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
I
InfoQ
H
Help Net Security
V2EX - 技术
V2EX - 技术
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Security Affairs
SecWiki News
SecWiki News
The Register - Security
The Register - Security
人人都是产品经理
人人都是产品经理
NISL@THU
NISL@THU
小众软件
小众软件
B
Blog
T
Threatpost
P
Palo Alto Networks Blog
博客园 - 【当耐特】
L
LangChain Blog
AWS News Blog
AWS News Blog
月光博客
月光博客
宝玉的分享
宝玉的分享

博客园 - 曲达子

Oralce sys system密码找回 oracle服务丢失的解决办法 JS 实现table 分页 xmlHttp 中乱码处理 在oc4j中安装、配置MapViewer 关于PostBack(转) 自定义控件属性的一些特性 oracle 游标使用 (转)实用JaveScript 用.NET 2.0压缩/解压封装的类 (转) ASP.NET 项目中用到的广告效果(转) js 在杂烩 在NHibernate中使用Oracle的sequence主键 window对象详解 asp.net 获取服务器信息 路径问题 刷新父窗口 js中一些鼠标事件 常见问题与错误小总结
C# windows 服务(转)
曲达子 · 2009-02-12 · via 博客园 - 曲达子

前言:编写一个Windows服务程序,定时从数据库中拿出记录发送邮件。

测试环境:Visual Studio 2005 SP1、Windows Server 2003 SP2

一、新建项目

打开VS2005,新建一个“Windows 服务”项目。

二、添加Timer

展开“工具箱”,在“组件”标签下找到“Timer”双击,这时就添加了一个Timer组件,修改“Name”属性为“timEmail”、“Enabled”为“false”、“Interval”为“60000”。

接下来要做一些修补工作,不知是VS2005的BUG还是我没找着地方,在VS2003下是不存在该问题的:刚从“组件”下添加的“Timer”按理说应该来自“System.Timers命名空间”,也只有“System.Timers.Timer”才能在Windows服务程序中正常工作,但是现在这个Timer却是属于“System.Windows.Forms.Timer”的。所以得稍作修改,打开“.Designer.cs”文件,修改如下:

#region 组件设计器生成的代码

//........以上略
/// <summary> 
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
            
this.components = new System.ComponentModel.Container();
            
//this.timEmail = new System.Windows.Forms.Timer(this.components);原
            this.timEmail = new System.Timers.Timer();//
            this.timEmail.Interval = 60000;
            
this.ServiceName = "Service1";

}
#endregion
//private System.Windows.Forms.Timer timEmail;原
private System.Timers.Timer timEmail;//

 三、添加配置文件

服务每次调用配置文件,获取一些基本参数,这样一些变更就可直接修改配置文件而不必修改代码。新建ServiceConfig.xml存放于项目“Bin\Debug\”下:

<?xml version="1.0" encoding="utf-8" ?> 
<serviceConfig>
    
<serviceItem 
        
name="sendEmail" 
        enable
="true" 
        elapsed
="60000" 
        connectionString
="your database connection..." 
        smtp
="smtp address" 
        account
="your email account..." 
        password
="your password..." >
    
</serviceItem>
</serviceConfig>

四、以下是实现代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Xml;//操作配置文件
using System.IO;//写日志
using System.Threading;//使用线程

namespace ClientWindowsService
{
    
public partial class ClientService : ServiceBase
    {
        
public ClientService()
        {
            InitializeComponent();
        }
protected override void OnStart(string[] args)
        {
            
//服务启动
      this.timEmail.Enabled = true;
            
this.tSendEmail();
        }
protected override void OnStop()
        {
            
//服务停止
      this.timEmail.Enabled = false;
        }
private void timEmail_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            
//定时器
      this.tSendEmail();
        }
//开启新进程发送邮件
    private void tSendEmail()
        {
            Thread t 
= new Thread(new ThreadStart(sendEmail));
            t.Start();
        }
//发送邮件函数
    private void sendEmail()
        {
            XmlDocument doc 
= new XmlDocument();
            
//添加System.Windows.Forms引用,获取执行目录
      string configFile = System.Windows.Forms.Application.StartupPath.ToString() + "\ServiceConfig.xml";
            doc.Load(@configFile);
            XmlElement root 
= doc.DocumentElement;
            
foreach (XmlNode node in root)
            {
                
//如果配置文件中开启服务
        if (node.Attributes["name"].Value == "sendEmail" && node.Attributes["enable"].Value == "true")
                {
                    
try
                    {
                        
//读取数据库,发送邮件操作,略
                    }
                    
catch (Exception error)
                    {
                        
//写错误日志
            using (StreamWriter sw = new StreamWriter(System.Windows.Forms.Application.StartupPath.ToString() + @"" + DateTime.Now.ToString("yyyy-MM-dd"+ ".txt"true, System.Text.Encoding.UTF8))
                        {
                            sw.WriteLine(DateTime.Now.ToString() 
+ "");
                            sw.WriteLine(error.ToString());
                            sw.WriteLine(
"---------------------------------------------");
                            sw.Close();
                        }
                    }
                }
            }
//end foreach
        }

    }

//end class
}//end namespace

五、布署服务

在设计模式下右键-->添加安装程序-->设置serviceProcessInstaller1的Account为LocalSystem

设置serviceInstaller1的StartType为Automatic

编译

在命令模式下执行:%systemroot%\microsoft.net\framework\v2.0.50727\installUtil.exe D:\项目目录\bin\Debug\可执行文件名.exe
在每次需要修改Windows服务时,这就会要求你卸载和重新安装这个服务。不过要注意在卸载这个服务前,最好确保服务管理控制台已经关闭,这会是一个很好的习惯。如果没有这样操作的话,你可能在卸载和重安装Windows服务时会遇到麻烦。仅卸载服务的话,可以执行相的InstallUtil命令用于注销服务,不过要在后面加一个/u命令开关。

调试Windows服务

  从另外的角度度看,调试Windows服务绝不同于一个普通的应用程序。调试Windows服务要求的步骤更多。服务不能象你对普通应用程序做的那样,只要简单地在开发环境下执行就可以调试了。服务必须首先被安装和启动,这一点在前面部分我们已经做到了。为了便于跟踪调试代码,一旦服务被启动,你就要用Visual Studio把运行的进程附加进来(attach)。记住,对你的Windows服务做的任何修改都要对这个服务进行卸载和重安装。


附加正在运行的Windows服务

  为了调试程序,有些附加Windows服务的操作说明。这些操作假定你已经安装了这个Windows服务并且它正在运行。

1. 用Visual Studio装载这个项目
2. 点击“调试”菜单
3. 点击“进程”菜单
4. 确保 显示系统进程 被选
5. 在 可用进程 列表中,把进程定位于你的可执行文件名称上点击选中它
6. 点击 附加 按钮
7. 点击 确定
8. 点击 关闭
9. 在timer1_Elapsed方法里设置一个断点,然后等它执行