本文实例讲述了asp.net基于windows服务实现定时发送邮件的方法。分享给大家供大家参考,具体如下:
//定义组件private System.Timers.Timer time;public int nowhour;public int minutes;public string sendTime;public Thread th;public string isOpen;//是否启用定时发送public string strToEUser;public static int index = -1;public static ArrayList mulitaddress;//服务开始protected override void OnStart(string[] args){time = new System.Timers.Timer();time.Enabled = true;time.AutoReset = true;//定时执行方法 time.Elapsed+=new System.Timers.ElapsedEventHandler(time_Elapsed);UserEmail toUser =new UserEmail();mulitaddress = GetMailAdressName(); // LogHelper.SaveNote("当前索引的值" + index.ToString());Thread.Sleep(2000); time.Start();}public class LogHelper{public static void SaveNote(string note){FileStream stream = new FileStream(GetLogDirectory("Common") + DateTime.Now.ToString("yyyy-MM-dd") + ".txt", FileMode.Append, FileAccess.Write, FileShare.Delete | FileShare.ReadWrite);StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);writer.WriteLine("================================================================");writer.WriteLine(string.Format("Note:/t{0}", note));writer.WriteLine(string.Format("DateTime:/t{0}/r/n/r/n",DateTime.Now.ToString()));stream.Flush();writer.Close();stream.Close();stream.Dispose();writer.Dispose();}public static void SaveNote(string note, string txtname){FileStream stream = new FileStream(GetLogDirectory(txtname) + DateTime.Now.ToString("yyyy-MM-dd") + ".txt", FileMode.Append, FileAccess.Write, FileShare.Delete | FileShare.ReadWrite);StreamWriter writer = new StreamWriter(stream, Encoding.GetEncoding("gb2312"));writer.WriteLine("================================================================");writer.WriteLine(string.Format("Note:/t{0}", note));writer.WriteLine(string.Format("DateTime:/t{0}/r/n/r/n", DateTime.Now.ToString("yyyyMMddHHmmss")));stream.Flush();writer.Close();stream.Close();stream.Dispose();writer.Dispose();}public static void SaveException(Exception e){SaveException(e, string.Empty);}public static void SaveException(Exception e, string memo){FileStream stream = new FileStream(GetLogDirectory("Common") + DateTime.Now.ToString("yyyy-MM-dd") + ".txt", FileMode.Append, FileAccess.Write, FileShare.Delete | FileShare.ReadWrite);StreamWriter writer = new StreamWriter(stream);writer.WriteLine("================================================================");writer.WriteLine(string.Format("Memo:/t{0}", memo));writer.WriteLine(string.Format("DateTime:/t{0}", DateTime.Now.ToShortTimeString()));writer.WriteLine(string.Format("Message:/t{0}", e.Message));writer.WriteLine(string.Format("StackTrace:/r/n----------/r/n{0}/r/n----------/r/n/r/n/r/n", e.StackTrace));stream.Flush();writer.Close();stream.Close();stream.Dispose();writer.Dispose();}public static string GetLogDirectory(string category){string baseDirectory = string.Empty;if ((HttpContext.Current != null) && (HttpContext.Current.Server != null)){baseDirectory = HttpContext.Current.Server.MapPath("~");}else{baseDirectory = AppDomain.CurrentDomain.BaseDirectory;}if ((baseDirectory[baseDirectory.Length - 1] != "/") && (baseDirectory[baseDirectory.Length - 1] != "//")){baseDirectory = baseDirectory + @"/";}baseDirectory = string.Format(@"{0}Log/{1}/", baseDirectory, category);if (!Directory.Exists(baseDirectory)){Directory.CreateDirectory(baseDirectory);}return baseDirectory;}}void time_Elapsed(object sender, System.Timers.ElapsedEventArgs e){try{if (mulitaddress != null){LogHelper.SaveNote("进入time_Elapsed");//获取定时发送时间sendTime = Convert.ToString(GetConfigValue("sendTime"));LogHelper.SaveNote("sendTime" + sendTime);//是否开启定时发送功能isOpen = GetConfigValue("isOpen");int sleeptime = Convert.ToInt32(GetConfigValue("SleepTime"));int stoptime = Convert.ToInt32(GetConfigValue("stoptime"));//LogHelper.SaveNote("数组长度" + mulitaddress.Count);// LogHelper.SaveNote("是否开启定时发送功能" + isOpen + "定时时间" + sendTime + "定时小时数:" + Convert.ToInt32(sendTime.Split(new char[] { ":" })[0]) + "定时分钟数:" + Convert.ToInt32(sendTime.Split(new char[] { ":" })[1]));if (isOpen == "true"){//现在时间 小时nowhour = Convert.ToInt32(DateTime.Now.Hour.ToString());//10//现在分钟minutes = Convert.ToInt32(DateTime.Now.Minute.ToString());//5//获取发送小时int sendhour = Convert.ToInt32(sendTime.Split(new char[] { ":" })[0]);//获取发送的分钟int sendMinute = Convert.ToInt32(sendTime.Split(new char[] { ":" })[1]);LogHelper.SaveNote("进入定时发送邮件服务! 定时小时为:" + sendhour.ToString() + "定时分钟为:" + sendMinute.ToString() + "现在小时为:" + nowhour.ToString() + "现在定时的分钟为:" + minutes.ToString());LogHelper.SaveNote("当前索引的值" + index.ToString());if (nowhour == stoptime){LogHelper.SaveNote("停止时间点到了 邮件停止发送 !!!");index = -1;}else{//如果和当前的时间 小时相等 则定时发送邮件if ((Convert.ToDateTime(DateTime.Now.ToShortTimeString()) >= Convert.ToDateTime(sendTime)) && index < mulitaddress.Count){index++;if (index < mulitaddress.Count){SendEmail(((UserEmail)mulitaddress[index]));}else{LogHelper.SaveNote("发送完毕 当前的索引值为" + index.ToString());}}}}else{//LogHelper.SaveNote("当前索引的值" + index.ToString());index++;if (index < mulitaddress.Count){SendEmail(((UserEmail)mulitaddress[index]));}else{LogHelper.SaveNote("发送完毕 时间停止");time.Enabled = false;time.Stop();}}Thread.Sleep(sleeptime);}elseLogHelper.SaveNote("mulitaddress=null");}catch (Exception ex) {LogHelper.SaveNote(ex.ToString());}}public ArrayList GetMailAdressName(){ArrayList list = new ArrayList();string strSQL = "select b.mailAddress, a.mailtemplate,a.title from tg_product as a inner join tg_mailOrder as b on a.ccode=b.ccode where a.createtime=(select max(createtime) from tg_product)";SqlDataReader dr = SqlHelper.ExecuteReader(CommandType.Text, strSQL, null);if (dr.HasRows){while (dr.Read()){UserEmail email = new UserEmail();email.Mailaddres = dr["mailAddress"].ToString();email.Title = dr["title"].ToString();email.Contents = dr["mailtemplate"].ToString();list.Add(email);}}return list;}/// <summary>/// 定义用户邮件 标题 内容 Email地址/// </summary>public class UserEmail {private string title;private string contents;public string Contents{get { return contents; }set { contents = value; }}private string mailaddres;public string Mailaddres{get { return mailaddres; }set { mailaddres = value; }}public string Title { get{return title;}set { title = value; }}}#region 发送邮件/// <summary>/// 发送邮件/// </summary>public void SendEmail(UserEmail user){try{LogHelper.SaveNote("进入SendEmail!!!");//邮件服务器string smtpserver = GetConfigValue("smtpserver");//发件人的邮箱名称string emailuserName = GetConfigValue("emailuserName");//发件人的邮箱密码string emailuserpwd = GetConfigValue("emailuserpwd");//邮箱地址string emailfrom = GetConfigValue("emailfrom");int port = Convert.ToInt32(GetConfigValue("serverPort"));bool f = true;//是否经过SSL加密string isSSL = GetConfigValue("SSL");if (isSSL == "true"){f = true;}else{f = false;}LogHelper.SaveNote("发件人的邮箱名称" + emailuserName + "邮件地址(emailFrom)" + emailfrom + "收件人" + user.Mailaddres);SendEmailToUser(smtpserver, port, f, user.Mailaddres, null, emailuserName, emailuserpwd, emailfrom, user.Title,user.Contents);LogHelper.SaveNote("Send Mail Success");}//获取异常信息catch (Exception error){//写入异常信息using (StreamWriter sw = new StreamWriter("F://MailErrorlog.txt", true, System.Text.Encoding.UTF8)){sw.WriteLine(DateTime.Now.ToString() + ":");sw.WriteLine("Exception 异常信息如下.................");sw.WriteLine(error.ToString());sw.WriteLine("---------------------------------------------");sw.Close();}}}#endregion#region 利用.Net自带类(SmtpClient) 发送邮件/// <summary>/// 利用.Net自带类(SmtpClient) 发送邮件/// </summary>/// <param name="stmpserver">邮件服务器</param>/// <param name="username">用户名(邮箱名称)</param>/// <param name="pwd">密码</param>/// <param name="f">是否经过SSL加密</param>/// <param name="port">邮件服务器端口(没有加密 一般都是25)</param>/// <param name="strfrom">发件人</param>/// <param name="strto">收件人</param>/// <param name="subject">主题</param>/// <param name="body">内容</param>/// <param name="Mulitaddress">发送多人 收件人的邮箱地址以逗号隔开</param>/// <param name="attachmentName">发送的附件名称 没有附件则为null or ""</param>public void SendEmailToUser(string stmpserver,int port,bool f, string Mulitaddress, string attachmentName, string username, string pwd, string strfrom, string subject, string body){string ErrorLog = GetConfigValue("ErrorLog");SmtpClient smtp = new SmtpClient();//发送邮件的方式smtp.DeliveryMethod = SmtpDeliveryMethod.Network;//指定邮件服务器smtp.Host = stmpserver;//Gmail QQ stmp ssl加密使用的端口 smtp.Port = port;smtp.EnableSsl = f; ;//true 经过ssl加密 //验证发件人的身份 用户名(邮件地址和密码)smtp.Credentials = new System.Net.NetworkCredential(username, pwd);//初始化信息(来自 接收人)MailMessage _mailmessage = new MailMessage();//_mailmessage.To = strto;//发送多个人 接收人邮件地址以,隔开_mailmessage.From = new MailAddress(strfrom);_mailmessage.To.Add(Mulitaddress);//如果发送失败,SMTP 服务器将发送 失败邮件通知_mailmessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;//优先级_mailmessage.Priority = MailPriority.High;//发送主题_mailmessage.Subject = subject;//有附件则添加附件if (!string.IsNullOrEmpty(attachmentName)){System.Net.Mail.Attachment attch = new System.Net.Mail.Attachment(attachmentName);_mailmessage.Attachments.Add(attch);}//邮件主题编码_mailmessage.SubjectEncoding = System.Text.Encoding.UTF8;//指定发送的格式 (Html)_mailmessage.IsBodyHtml = true;//指定发送邮件的编码_mailmessage.BodyEncoding = System.Text.Encoding.UTF8;//指定邮件内容_mailmessage.Body = body;//发送邮件try{smtp.Send(_mailmessage);}catch (Exception ex){using (StreamWriter writer = new StreamWriter(ErrorLog+"://MailErrorlog.txt", true, System.Text.Encoding.UTF8)){writer.WriteLine("---------------------------------------------");writer.WriteLine("SendEmail方法发送邮件错误日志................");writer.WriteLine(ex.ToString());writer.Flush();writer.Close();}}}#endregion#region 获取邮件配置节点的值/// <summary>/// 加载相应配置文件 并按节点名称获取对应的值/// </summary>/// <param name="target">当前节点的名称</param>/// <returns>返回当前节点名称所对应的值</returns>public string GetConfigValue(string target){string configpath=System.Windows.Forms.Application.StartupPath.ToString() + "/Email.config";return GetConfigValue(configpath, target);}/// <summary>/// 根据节点名称获取配置文件对应的值(邮件配置信息)/// </summary>/// <param name="configpath">配置文件路径</param>/// <param name="target">要获取配置节点的名称</param>/// <returns>返回当前节点名称所对应的值</returns>public string GetConfigValue(string configpath, string target){XmlDocument doc = new XmlDocument();//加载文件路径sdoc.Load(configpath);//获取当前节点的根节点XmlElement root = doc.DocumentElement;//获取当前节点下所有匹配子节点元素XmlNodeList xmlnode = root.GetElementsByTagName(target);//返回值return xmlnode[0].InnerXml;}#endregion//服务结束protected override void OnStop(){time.Enabled = false;}Email.Config如下:
<?xml version="1.0" encoding="utf-8"?><Emailconfig> <!--邮件服务器地址 Gmail stmp.gmail.com--> <smtpserver>*****</smtpserver> <!--邮箱用户名 --> <emailuserName>***</emailuserName> <!--邮箱密码--> <emailuserpwd>****</emailuserpwd> <!--邮箱地址--> <emailfrom>*****</emailfrom> <!--是否启用定时发送邮件功能--> <isOpen>true</isOpen> <!--前提下isOpen为true 定在每天某个时间点发送邮件--> <sendTime>8:53</sendTime><!--是否经过SSL加密--><SSL>false</SSL> <!--Gmail smtp SSL加密 (Gmail:587) 服务器端口(没有加密(SSL 配置为false) 一般都是25(163,qq))--> <serverPort>25</serverPort> <!--线程睡眠时间--> <SleepTime>1000</SleepTime> <!--定停发送时间--> <stoptime>0</stoptime> <!--发送邮件错误日志路径 盘根目录--> <ErrorLog>E</ErrorLog> <!--定义数据库连接字符串--> <Connstr></Connstr></Emailconfig>
SQLHelper如下:
#region 数据库操作类的封装public abstract class SqlHelper{//Database connection stringspublic static readonly string ConnectionStringLocalTransaction = Connstr;// Hashtable to store cached parametersprivate static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());/*返回数据库连接*/public static SqlConnection getConnection(){SqlConnection c = new SqlConnection(ConnectionStringLocalTransaction);return c;}/// <summary>/// Execute a SqlCommand that returns a resultset against the database specified in the connection string /// using the provided parameters./// </summary>/// <remarks>/// e.g.: /// SqlDataReader r = ExecuteReader(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));/// </remarks>/// <param name="connectionString">a valid connection string for a SqlConnection</param>/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>/// <param name="commandText">the stored procedure name or T-SQL command</param>/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>/// <returns>A SqlDataReader containing the results</returns>public static SqlDataReader ExecuteReader(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters){SqlCommand cmd = new SqlCommand();SqlConnection conn = new SqlConnection(connectionString);// we use a try/catch here because if the method throws an exception we want to // close the connection throw code, because no datareader will exist, hence the // commandBehaviour.CloseConnection will not worktry{PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);cmd.Parameters.Clear();return rdr;}catch{conn.Close();throw;}}public static DataSet ReturnDataSet(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters){SqlCommand cmd = new SqlCommand();SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);// we use a try/catch here because if the method throws an exception we want to // close the connection throw code, because no datareader will exist, hence the // commandBehaviour.CloseConnection will not worktry{PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);DataSet ds = new DataSet();SqlDataAdapter sda = new SqlDataAdapter(cmd);sda.Fill(ds);return ds;}catch{conn.Close();throw;}}/// <summary>/// Execute a SqlCommand that returns a resultset against the database specified in the connection string /// using the provided parameters./// </summary>/// <remarks>/// e.g.: /// SqlDataReader r = ExecuteReader(SqlConnection, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));/// </remarks>/// <param name="connectionString">a valid connection string for a SqlConnection</param>/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>/// <param name="commandText">the stored procedure name or T-SQL command</param>/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>/// <returns>A SqlDataReader containing the results</returns>public static SqlDataReader ExecuteReader(SqlConnection conn, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters){SqlCommand cmd = new SqlCommand();// we use a try/catch here because if the method throws an exception we want to // close the connection throw code, because no datareader will exist, hence the // commandBehaviour.CloseConnection will not worktry{PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);cmd.Parameters.Clear();return rdr;}catch{conn.Close();throw;}}/// <summary>/// Execute a SqlCommand that returns a resultset against the database specified in the connection string /// using the provided parameters./// </summary>/// <remarks>/// e.g.: /// SqlDataReader r = ExecuteReader(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));/// </remarks>/// <param name="connectionString">a valid connection string for a SqlConnection</param>/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>/// <param name="commandText">the stored procedure name or T-SQL command</param>/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>/// <returns>A SqlDataReader containing the results</returns>public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters){SqlCommand cmd = new SqlCommand();SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);// we use a try/catch here because if the method throws an exception we want to // close the connection throw code, because no datareader will exist, hence the // commandBehaviour.CloseConnection will not worktry{PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);cmd.Parameters.Clear();return rdr;}catch{conn.Close();throw;}}/// <summary>/// add parameter array to the cache/// </summary>/// <param name="cacheKey">Key to the parameter cache</param>/// <param name="cmdParms">an array of SqlParamters to be cached</param>public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters){parmCache[cacheKey] = commandParameters;}/// <summary>/// Retrieve cached parameters/// </summary>/// <param name="cacheKey">key used to lookup parameters</param>/// <returns>Cached SqlParamters array</returns>public static SqlParameter[] GetCachedParameters(string cacheKey){SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];if (cachedParms == null)return null;SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length];for (int i = 0, j = cachedParms.Length; i < j; i++)clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone();return clonedParms;}/// <summary>/// Prepare a command for execution/// </summary>/// <param name="cmd">SqlCommand object</param>/// <param name="conn">SqlConnection object</param>/// <param name="trans">SqlTransaction object</param>/// <param name="cmdType">Cmd type e.g. stored procedure or text</param>/// <param name="cmdText">Command text, e.g. Select * from Products</param>/// <param name="cmdParms">SqlParameters to use in the command</param>private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms){if (conn.State != ConnectionState.Open)conn.Open();cmd.Connection = conn;cmd.CommandText = cmdText;if (trans != null)cmd.Transaction = trans;cmd.CommandType = cmdType;if (cmdParms != null){foreach (SqlParameter parm in cmdParms)cmd.Parameters.Add(parm);}}/// <summary>/// 传入输入参数/// </summary>/// <param name="ParamName">存储过程名称</param>/// <param name="DbType">参数类型</param></param>/// <param name="Size">参数大小</param>/// <param name="Value">参数值</param>/// <returns>新的 parameter 对象</returns>public static SqlParameter MakeInParam(string ParamName, SqlDbType DbType, int Size, object Value){return MakeParam(ParamName, DbType, Size, ParameterDirection.Input, Value);}public void MakeInParam(ref string OldString, string ParamName, SqlDbType DbType, int Size, object Value){OldString = OldString.Replace(ParamName, (string)Value);}/// <summary>/// 传入返回值参数/// </summary>/// <param name="ParamName">存储过程名称</param>/// <param name="DbType">参数类型</param>/// <param name="Size">参数大小</param>/// <returns>新的 parameter 对象</returns>public static SqlParameter MakeOutParam(string ParamName, SqlDbType DbType, int Size){return MakeParam(ParamName, DbType, Size, ParameterDirection.Output, null);}/// <summary>/// 传入返回值参数/// </summary>/// <param name="ParamName">存储过程名称</param>/// <param name="DbType">参数类型</param>/// <param name="Size">参数大小</param>/// <returns>新的 parameter 对象</returns>public static SqlParameter MakeReturnParam(string ParamName, SqlDbType DbType, int Size){return MakeParam(ParamName, DbType, Size, ParameterDirection.ReturnValue, null);}/// <summary>/// 生成存储过程参数/// </summary>/// <param name="ParamName">存储过程名称</param>/// <param name="DbType">参数类型</param>/// <param name="Size">参数大小</param>/// <param name="Direction">参数方向</param>/// <param name="Value">参数值</param>/// <returns>新的 parameter 对象</returns>public static SqlParameter MakeParam(string ParamName, SqlDbType DbType, Int32 Size, ParameterDirection Direction, object Value){SqlParameter param;if (Size > 0)param = new SqlParameter(ParamName, DbType, Size);elseparam = new SqlParameter(ParamName, DbType);param.Direction = Direction;if (!(Direction == ParameterDirection.Output && Value == null))param.Value = Value;return param;}/// <summary>/// 创建 SqlCommand 对象实例(用来返回一个整数值)/// </summary>/// <param name="storedProcName">存储过程名</param>/// <param name="parameters">存储过程参数</param>/// <returns>SqlCommand 对象实例</returns>private static SqlCommand BuildIntCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters){SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);command.Parameters.Add(new SqlParameter("ReturnValue",SqlDbType.Int, 4, ParameterDirection.ReturnValue,false, 0, 0, string.Empty, DataRowVersion.Default, null));return command;}/// <summary>/// 构建 SqlCommand 对象(用来返回一个结果集,而不是一个整数值)/// </summary>/// <param name="connection">数据库连接</param>/// <param name="storedProcName">存储过程名</param>/// <param name="parameters">存储过程参数</param>/// <returns>SqlCommand</returns>private static SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters){SqlCommand command = new SqlCommand(storedProcName, connection);command.CommandType = CommandType.StoredProcedure;foreach (SqlParameter parameter in parameters){ command.Parameters.Add(parameter);}return command;}#region 执行查询语句 返回dataset/// <summary>/// 执行查询语句,返回DataSet/// </summary>/// <param name="cmdText">查询语句</param>/// <returns>DataSet</returns>public static DataSet GetDataSet(string cmdText){using (SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction)){SqlCommand sqlcmd = new SqlCommand(cmdText, conn);sqlcmd.CommandTimeout = 1000;SqlDataAdapter cmd = new SqlDataAdapter(sqlcmd);DataSet ds = new DataSet();try{conn.Open();cmd.Fill(ds, "mydt");return ds;}catch (Exception ex){conn.Close();cmd.Dispose();conn.Dispose();throw new Exception(ex.Message);}finally{cmd.Dispose();conn.Close();conn.Dispose();}}}#endregion}#endregion将C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/InstallUtil.exe 拷贝到执行的目录Bin Debug文件下 然后注册windows服务
复制代码 代码如下:InstallUtil.exe windowservice.exe
卸载windows服务:
复制代码 代码如下:InstallUtil.exe -u windowservice.exe
希望本文所述对大家asp.net程序设计有所帮助。