using System; using System.Collections.Generic; using System.Linq; using System.Text; using Quartz; using System.Data; using System.Data.SqlClient; using System.Configuration; using System.Reflection; using System.IO; using System.Net.Mail; using System.Net; namespace ICSSoft.SendMail { public class ICSMail : IJob { private static object key = new object(); private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public void Execute(IJobExecutionContext context) { try { lock (key) { log.Info("开始……………………………………………………………………"); Execute(); log.Info("结束……………………………………………………………………"); } } catch (Exception ex) { log.Error(ex.ToString()); } } public void Execute() { try { string conStr = GetConfigString(); #region SQL string sql = @"SELECT ID, SendHost, SendPort, SendDisplayName, SendAddress, SendPassword, TOAddress, CCAddress, Subject, IsBodyHtml, Body FROM dbo.ICSSendMail WHERE Status='0' OR (Retry='1' AND Status='2') ORDER BY CreatTIME"; DataTable dt = GetDate(conStr, sql); foreach (DataRow dr in dt.Rows) { try { SendEmail(dr["SendHost"].ToString(), Convert.ToInt32(dr["SendPort"]), dr["SendDisplayName"].ToString(), dr["SendAddress"].ToString(), dr["SendPassword"].ToString(), dr["TOAddress"].ToString(), dr["CCAddress"].ToString(), dr["Subject"].ToString(), Convert.ToBoolean(dr["IsBodyHtml"]), dr["Body"].ToString()); string sqlUpdate = string.Format("UPDATE ICSSendMail SET Status='1',ModifyTIME=GETDATE() WHERE ID='{0}'", dr["ID"].ToString()); ExecuteDate(conStr, sqlUpdate); } catch (Exception ex) { string sqlUpdate = string.Format("UPDATE ICSSendMail SET Status='2',Message='{1}',ModifyTIME=GETDATE() WHERE ID='{0}'", dr["ID"].ToString(),ex.Message); ExecuteDate(conStr, sqlUpdate); } } #endregion } catch (Exception ex) { log.Error(ex.ToString()); } } #region 读取配置文件 public static string GetConfigString() { try { Configuration config = GetConfig(); string configString = config.ConnectionStrings.ConnectionStrings["SysConnectionString"].ConnectionString.ToString(); return configString; } catch (Exception) { throw; } } public static Configuration GetConfig() { Assembly assembly = Assembly.GetCallingAssembly(); string path = string.Format("{0}.config", assembly.Location); if (!File.Exists(path)) { throw new FileNotFoundException(path + "路径下的文件未找到!"); } try { ExeConfigurationFileMap configFile = new ExeConfigurationFileMap(); configFile.ExeConfigFilename = path; Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None); return config; } catch (Exception) { throw; } } #endregion #region 执行sql public static DataTable GetDate(string conStr, string sql) { try { using (SqlConnection con = new SqlConnection(conStr)) { con.Open(); try { Dictionary dictionary = new Dictionary(); using (SqlTransaction tran = con.BeginTransaction()) { using (SqlCommand command = new SqlCommand()) { command.Connection = con; command.Transaction = tran; command.CommandText = sql; try { using (SqlDataAdapter da = new SqlDataAdapter(command)) { DataTable dt = new DataTable(); da.Fill(dt); return dt; } } catch (Exception ex) { tran.Rollback(); log.Error(ex.ToString() + Environment.NewLine + "异常SQL:" + Environment.NewLine + sql); } return null; } } } catch (Exception ex) { log.Error(ex.ToString()); throw ex; } finally { if (con.State == ConnectionState.Open) con.Close(); con.Dispose(); } } } catch (Exception ex) { log.Error(ex.ToString()); throw ex; } } public static void ExecuteDate(string conStr, string sql) { try { using (SqlConnection con = new SqlConnection(conStr)) { con.Open(); try { using (SqlTransaction tran = con.BeginTransaction()) { using (SqlCommand command = new SqlCommand()) { command.Connection = con; command.Transaction = tran; command.CommandText = sql; try { int result = command.ExecuteNonQuery(); tran.Commit(); } catch (Exception ex) { tran.Rollback(); log.Error(ex.ToString() + Environment.NewLine + "异常SQL:" + Environment.NewLine + sql); } } } } catch (Exception ex) { log.Error(ex.ToString()); throw ex; } finally { if (con.State == ConnectionState.Open) con.Close(); con.Dispose(); } } } catch (Exception ex) { log.Error(ex.ToString()); throw ex; } } #endregion #region 发送邮件 /// /// 发送Email /// /// 发件服务器 /// 发件端口 /// 发件人显示名称 /// 发件人 /// 发件密码,需要AppConfig.ToMd5()加密后的密码 /// 接收人 /// 抄送人 /// 标题 /// 是否发送HTML格式的文本 /// 发件内容 public static void SendEmail(string SendHost, int SendPort, string SendDisplayName, string SendAddress, string SendPassword, string TOAddress, string CCAddress, string Subject, bool IsBodyHtml, string Body) { try { SendPassword = ICSSoft.Base.Config.AppConfig.AppConfig.FromMd5(SendPassword); //设置smtp var smtp = new SmtpClient { EnableSsl = true, //使用安全加密连接。 //UseDefaultCredentials必须放在Credentials前面,否则会报错(不允许使用邮箱名称。 服务器响应为:authentication is required,126 smtp8,NORpCgDnjYEC52FedcbIGQ--.1581S2 1583474434) UseDefaultCredentials = false, //不和请求一块发送。 Host = SendHost, //Port = SendPort, Credentials = new NetworkCredential(SendAddress,SendPassword) }; //qq企业邮箱不能设置端口号,否则发送失败 if (SendPort != 0) smtp.Port = SendPort; ////开一个Message var mail = new MailMessage { Subject = Subject, SubjectEncoding = Encoding.GetEncoding("utf-8"), BodyEncoding = Encoding.GetEncoding("utf-8"), From = new MailAddress(SendAddress, SendDisplayName), IsBodyHtml = IsBodyHtml, Body = Body }; string[] toList = TOAddress.Split(','); foreach (var to in toList) { if (!string.IsNullOrEmpty(to)) { mail.To.Add(to); } } string[] ccList = CCAddress.Split(','); foreach (var cc in ccList) { if (!string.IsNullOrEmpty(cc)) { mail.CC.Add(cc); } } #region //加这段之前用公司邮箱发送报错:根据验证过程,远程证书无效 //加上后解决问题 ServicePointManager.ServerCertificateValidationCallback = delegate(Object obj, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors) { return true; }; #endregion smtp.Send(mail); //var ised = new InternalSendEmailDelegate(smtp.Send); //var result = ised.BeginInvoke(mail, null, null); } catch (System.Exception ex) { log.Error("邮件异常:" + ex.ToString()); throw; } } #region Nested type: InternalSendEmailDelegate private delegate void InternalSendEmailDelegate(MailMessage m); #endregion #endregion } }