上次用asp.net 利用 Global.asax 定时发送邮件
自动邮件,不稳定,用windows服务比较稳定,还有一个核心点没有解决,就是写excel到指定文件夹还不能实现,不知道权限哪里出了问题,待研究.
C,C++都可以写windows服务,这里只介绍一下用C#创建一个windows服务
我用的工具是:Microsoft Visual Studio 2010
数据库是:sql server 2008
打开vs,新建->项目->创建Windows服务项目(我的项目是Service1)->在设计视图-工具箱-组件-拖拽一个Timer控件->创建完成后切换到代码视图(F5)
Service1.cs代码如下(添加自己需要引用的dll)
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 jmail; using Excel; using System.IO; using System.Reflection; using System.Timers; using System.Threading; using System.Data.SqlClient; namespace WindowsService1 { public partial class Service1 : ServiceBase { public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { // TODO: 在此处添加代码以启动服务。 this.timEmail.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件; this.timEmail.AutoReset = true;//设置是执行一次(false)还是一直执行(true); this.timEmail.Elapsed += new ElapsedEventHandler(timEmail_Elapsed); this.timEmail.Start(); //System.Timers.Timer myTimer = new System.Timers.Timer(3600000);//1小时 //myTimer.Elapsed += new ElapsedEventHandler(timEmail_Elapsed); //myTimer.AutoReset = true;//设置是执行一次(false)还是一直执行(true); //myTimer.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件; //this.tSendEmail(); } protected override void OnStop() { // TODO: 在此处添加代码以执行停止服务所需的关闭操作。 this.timEmail.Enabled = false; this.timEmail.Stop(); } private void tSendEmail() { Thread t = new Thread(new ThreadStart(sendEmail)); t.Start(); } DataSet Bind() { string sr = ""; sr += "SELECT *"; sr += " FROM [table]"; DataSet ds1 = ExecuteDataSet(sr); return ds1; } private void sendEmail() { //定时器 string name = System.DateTime.Now.ToString("yyyyMMddhhmmss"); name += "windows"; string pFilePath = null; string receiver = "[email protected]";//收件箱(分号隔开) string AddRecipientCC = "";// "[email protected]";//抄送箱(分号隔开) string table = "windows服务启动定时邮件"; table += '\n'; table += "看到此信息代表发送成功!"; DataSet result = Bind(); System.Data.DataTable dt = result.Tables[0]; if (dt.Rows.Count > 0) { for (int j = 0; j < dt.Rows.Count; j++) { table += '\n'; table += dt.Rows[j][0].ToString(); } } //if (result != null) //{ // WriteExcel(result, name); // pFilePath = @"C:\" + name + ".xlsx";//附件,分号隔开 //} sendEmail("hsf", "[email protected]", "123333444", receiver, AddRecipientCC, "windows自动邮件", table, "smtp.163.com", pFilePath); } private void timEmail_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { //定时器 this.tSendEmail(); } public DataSet ExecuteDataSet(string sql) { string Cconstring = @"user id=sa;password=123123;Data Source=.;Database=HAHA"; DataSet ds = new DataSet(); SqlDataAdapter da = new SqlDataAdapter(); SqlCommand cmd = new SqlCommand(); da.SelectCommand = cmd; using (SqlConnection con = new SqlConnection(Cconstring)) { cmd.Connection = con; cmd.CommandText = sql; try { da.Fill(ds); } catch (Exception ex) { string msg = ex.Message; } finally { } } return ds; } /// <summary> /// DataSet数据写入Excel保存自定义名称到默认文件夹内(C:\SaveFile) /// </summary> /// <param name="ds">System.Data.DataSet数据</param> /// <param name="filename">文件名称(不含后缀)如"hahahah"</param> public static void WriteExcel(System.Data.DataSet ds, string filename) { System.Data.DataTable dt = ds.Tables[0]; //dt.Columns[0] //Excel.Application excel = new Excel.Application();//引用Excel对象 //excel.Application.Workbooks.Add(true );//引用Excel工作簿 //excel.Cells[ 1 , 1 ] = "First Row First Column"; //excel.Cells[ 1 , 2 ] = "First Row Second Column"; //excel.Cells[ 2 , 1 ] = "Second Row First Column"; //excel.Cells[2, 2] = "Second Row Second Column"; //excel.Visible = true; //使Excel可视 //创建Application对象 Excel.Application xApp = new Excel.ApplicationClass(); xApp.Visible = false; ////得到WorkBook对象, 可以用两种方式之一: 下面的是打开已有的文件 //Excel.Workbook xBook = xApp.Workbooks._Open(@"C:\SaveFile\az.xls", //Missing.Value, Missing.Value, Missing.Value, Missing.Value //, Missing.Value, Missing.Value, Missing.Value, Missing.Value //, Missing.Value, Missing.Value, Missing.Value, Missing.Value); Excel.Workbook xBook = xApp.Workbooks.Add(Missing.Value);//新建文件的代码 //指定要操作的Sheet,两种方式: Excel.Worksheet xSheet = (Excel.Worksheet)xBook.Sheets[1]; //Excel.Worksheet xSheet=(Excel.Worksheet)xApp.ActiveSheet; ////读取数据,通过Range对象 //Excel.Range rng1 = xSheet.get_Range("A1", Type.Missing); //rng1.Value2 = "aaa"; ////读取,通过Range对象,但使用不同的接口得到Range ////Excel.Range rng2 = (Excel.Range)xSheet.Cells[1,2]; ////rng2.Value2 = "bbb"; //((Excel.Range)xSheet.Cells[1, 2]).Value="ccc"; ////写入数据 //Excel.Range rng3 = xSheet.get_Range("B2", Missing.Value); //rng3.Value2 = "Hello"; //rng3.Interior.ColorIndex = 6; //设置Range的背景色 for (int i = 0; i < dt.Columns.Count; i++) { ((Excel.Range)xSheet.Cells[1, i + 1]).Value = dt.Columns[i].ColumnName; for (int j = 0; j < dt.Rows.Count; j++) { ((Excel.Range)xSheet.Cells[j + 2, i + 1]).Value = dt.Rows[j][i]; } } string pFilePath = @"C:\" + filename ?? System.DateTime.Now.ToString("yyyyMMddhhmmss") + ".xlsx"; ////保存方式一:保存WorkBook if (File.Exists(pFilePath)) { File.Delete(pFilePath); } xBook.SaveAs(pFilePath, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value); ////保存方式二:保存WorkSheet //xSheet.SaveAs(@"../SaveFile/CData2.xls", //Missing.Value, Missing.Value, Missing.Value, Missing.Value, //Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value); //保存方式三 //xBook.Save(); xSheet = null; xBook = null; xApp.Quit(); //这一句是非常重要的,否则Excel对象不能从内存中退出 xApp = null; } /// <summary> /// 发送邮件方法 /// </summary> /// <param name="senderuser">发件人显示发送时的名称</param> /// <param name="euser">发件人邮箱地址</param> /// <param name="epwd">发件人邮箱密码</param> /// <param name="receiver">收件人邮箱地址</param> /// <param name="AddRecipientCC">cc抄送邮箱地址</param> /// <param name="subject">邮件标题</param> /// <param name="body">邮件内容</param> /// <param name="eserver">邮件服务器smtp.harmony.com.cn</param> /// <param name="attachment">邮件附件;隔开,附件为空可传null</param> /// <returns>bool</returns> public bool sendEmail(string senderuser/*发件人显示发送时的名称*/, string euser/*发件人邮箱地址*/, string epwd/*发件人邮箱密码*/ , string receiver/*收件人邮箱地址*/, string AddRecipientCC/*cc抄送邮箱地址*/, string subject/*邮件标题*/, string body/*邮件内容*/ , string eserver/*邮件服务器smtp.harmony.com.cn*/, string attachment/*邮件附件;隔开,附件为空可传null*/)//9个参数 { jmail.MessageClass jmMessage = new jmail.MessageClass(); jmMessage.Charset = "GB2312"; jmMessage.ISOEncodeHeaders = false; jmMessage.From = euser; jmMessage.FromName = senderuser; jmMessage.Subject = subject; jmMessage.MailServerUserName = euser; jmMessage.MailServerPassWord = epwd; if (!string.IsNullOrEmpty(receiver)) { string[] recip = receiver.Replace(';', ';').Split(';'); foreach (string item in recip) { jmMessage.AddRecipient(item.Trim(), "", ""); } } if (!string.IsNullOrEmpty(AddRecipientCC)) { string[] cc = AddRecipientCC.Replace(';', ';').Split(';'); foreach (string item in cc) { jmMessage.AddRecipientCC(item.Trim(), "", ""); } } jmMessage.Body = body; #region 附件 if (!string.IsNullOrEmpty(attachment)) { string[] attach = attachment.Split(';'); foreach (string item in attach) { string ContentType = ""; switch (item.Trim().Substring(item.LastIndexOf(".") + 1).ToLower()) { case "pdf": ContentType = "application/pdf"; break; case "jpg": case "jpeg": ContentType = "image/jpeg"; break; case "gif": ContentType = "image/gif"; break; case "png": ContentType = "image/png"; break; case "bmp": ContentType = "image/bmp"; break; case "zip": ContentType = "application/zip"; break; case "txt": ContentType = "text/plain"; break; case "htm": case "html": ContentType = "text/html"; break; case "doc": ContentType = "application/msword"; break; case "xls": ContentType = "application/vnd.ms-excel"; break; case "ppt": ContentType = "application/vnd.ms-powerpoint"; break; default: ContentType = "application/octet-stream"; break; } jmMessage.AddAttachment(item, true, ContentType); } } #endregion bool result = jmMessage.Send(eserver, false); jmMessage = null; return result; } } }
namespace WindowsService1 { partial class Service1 { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #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*60*2;//1分钟==2小时 this.timEmail.Interval = 10000;//10秒 this.ServiceName = "Service1"; } #endregion private System.Timers.Timer timEmail;//改 } }
serviceProcessInstaller1,右键属性更改属性视图中的Account属性为LocalService(本地服务)
serviceInstaller1,右键属性更改属性视图中的StartType属性为Automatic(自动)
运行程序(会报错,不过没关系只要已经生成了Service1.exe就没问题)
2.0版本找到文件C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe
3.0版本找到文件C:\WINDOWS\Microsoft.NET\Framework\v3.0\InstallUtil.exe
我用的framework 4.0
找到C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe
另外找到项目Service1\Service1\bin\Debug\Service1.exe
把这两个文件复制到单独的文件夹比如D:\autoMail
然后去Windows服务器注册就好了
开始--运行--输入注册命令--确定
注册命令:D:/autoMail/InstallUtil.exe D:/autoMail/Service1.exe
如果想注销用:D:/autoMail/InstallUtil.exe D:/autoMail/Service1.exe -U
注册成功,在计算机右键管理-服务里就会看到已经注册好的Service1服务,右键启动即可.