C#邮件定时群发工具Atilia用法实例
作者:北风其凉 发布时间:2022-06-13 11:50:24
标签:C#,邮件,定时
本文实例讲述了C#邮件定时群发工具Atilia用法。分享给大家供大家参考。具体如下:
一、Atilia可以做什么
Atilia是一个基于命令行的C#程序,可以发送邮件给一个或多个人。Atilia通过QQ的SMTP服务发送邮件,可以发送附件,可以在配置文件中手动配置收信人。
二、运行Atilia需要什么
在Atilia应用程序的同一目录下,有如下文件
1)一个Attachments文件夹,Atilia会将里面所有的子文件(不含子文件夹及其中文件)视作附件发送给收信人
2)AddressBook.xml文件,用于配置收信人
3)Atilia.html文件,是被发送的邮件文本
这三个文件都位于编译环境中的根目录下,在“程序集属性→生成事件→后期生成事件命令行”中可以将编译环境中的文件复制到Debug目录中
xcopy "$(ProjectDir)Atilia.html" "$(TargetDir)" /Y
xcopy "$(ProjectDir)AddressBook.xml" "$(TargetDir)" /Y
xcopy "$(ProjectDir)Attachments\*" "$(TargetDir)\Attachments\" /Y
三、收信人的配置
收信人配置的规则很简单,保存在AddressBook.xml中
<?xml version="1.0" encoding="gb2312"?>
<!--通讯录-->
<Root Subject="测试邮件">
<Person Name="江有汜" Email="1239063237@qq.com" />
<Person Name="淫侠" Email="****@qq.com" />
</Root>
每一个Person代表了一个人,Name是后面Email的一个标识,Email是收信人的地址
Atilia运行后会将邮件发给通信录中存在的每一个Person
四、输入参数
1)没有输入参数:当即准备发送所有的邮件,发送前询问是否发送:要求输入(y/n)
2)两个输入参数:8位的年月日 和 6位的时分秒,如2014年9月30日23时40分00秒,就需要输入如下命令运行:Atilia 20140930 234000
五、程序代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Mime;
using System.Xml;
using System.Text.RegularExpressions;
namespace Atilia
{
class Program
{
static void Main(string[] args)
{
MailMessage mlmssg = new MailMessage();
mlmssg.From = new MailAddress("1254355584@qq.com");
//读取收信人列表
Console.WriteLine("正在读取收信人列表");
XmlDocument xdoc = new XmlDocument();
xdoc.Load("AddressBook.xml");
XmlNode xroot = xdoc.SelectSingleNode("Root");
foreach (var xe in xroot.ChildNodes)
{
//判断读取到的是XmlElement而不是注释
if (xe is XmlElement)
{
mlmssg.To.Add((xe as XmlElement).GetAttribute("Email"));
Console.WriteLine("增加收信人 {0} 邮箱地址为 {1}",
(xe as XmlElement).GetAttribute("Name"),
(xe as XmlElement).GetAttribute("Email"));
}
}
Console.WriteLine("正在生成邮件主题,设定编码格式");
mlmssg.Subject = (xroot as XmlElement).GetAttribute("Subject");
mlmssg.SubjectEncoding = System.Text.Encoding.UTF8;
Console.WriteLine("正在读取邮件内容(Atilia.html),设定编码格式");
mlmssg.Body = File.ReadAllText(
"Atilia.html", Encoding.GetEncoding("gb2312"));
mlmssg.BodyEncoding = System.Text.Encoding.UTF8;
mlmssg.IsBodyHtml = true;
Console.WriteLine("设定邮件发送级别:Normal");
mlmssg.Priority = MailPriority.Normal;
//mailMessage.ReplyTo = new MailAddress("1239063237@qq.com"); //已过时
//读取附件列表
Console.WriteLine("正在读取附件列表");
if (System.IO.Directory.Exists("Attachments"))
{
System.IO.DirectoryInfo dif = new DirectoryInfo("Attachments");
if (dif.GetFiles().Count() != 0) //只读取文件,不查看子文件夹
{
System.Net.Mail.Attachment att = null;
//查询文件夹中的各个文件
foreach (FileInfo f in dif.GetFiles())
{
//分类讨论几种文件类型
switch (f.Extension.ToLower())
{
case ".rar":
case ".zip":
{
att = new Attachment(f.FullName,
MediaTypeNames.Application.Zip);
}
break;
case ".pdf":
{
att = new Attachment(f.FullName,
MediaTypeNames.Application.Pdf);
}
break;
case ".rtf":
{
att = new Attachment(f.FullName,
MediaTypeNames.Application.Rtf);
}
break;
default: //其他格式不指定格式
{
att = new Attachment(f.FullName,
MediaTypeNames.Application.Octet);
}
break;
}
ContentDisposition cd = att.ContentDisposition;
cd.CreationDate = File.GetCreationTime(f.FullName);
cd.ModificationDate = File.GetLastWriteTime(f.FullName);
cd.ReadDate = File.GetLastAccessTime(f.FullName);
Console.WriteLine("成功添加附件 {0}", f.Name);
mlmssg.Attachments.Add(att);
}
}
}
//设定SMTP服务器
Console.WriteLine("准备设置SMTP服务");
SmtpClient smtpclt = new SmtpClient();
smtpclt.DeliveryMethod = SmtpDeliveryMethod.Network;
Console.WriteLine("正在填写SMTP服务器地址");
smtpclt.Host = "smtp.qq.com";
Console.WriteLine("正在填写登录账户和登录密码");
smtpclt.Credentials =
new System.Net.NetworkCredential("1254355584", "****");
//没有指定时间
if (args.Length == 0)
{
//发送邮件前的最后提示
while (true)
{
Console.WriteLine("您确实要发送这些邮件吗? (y/n)");
string result;
result = Console.ReadLine();
result = result.ToLower().Trim();
if (result == "y")
{
break;
}
else if (result == "n")
{
Environment.Exit(0);
}
else
{
Console.WriteLine("输入错误");
}
}
}
else
{
int time_a = 0; //年月日
int time_b = 0; //时分秒
int time_now_a;
int time_now_b;
try
{
//时间分为两部分
//前一部分是8位数字表示的时间 如:20140930
//后一部分是4位数字表示的时间 如:210755
if (args.Length != 2)
{
throw new Exception("参数不正确");
}
//年月日
if (!Regex.IsMatch(args[0], "^[0-9]{8}$"))
{
throw new Exception("错误的时间数据");
}
bool b1 = int.TryParse(args[0], out time_a);
//时分秒
if (!Regex.IsMatch(args[1], "^[0-9]{6}$"))
{
throw new Exception("错误的时间数据");
}
bool b2 = int.TryParse(args[1], out time_b);
if ((!b1) || (!b2))
{
throw new Exception("时间数据转换失败");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine("命令示例: Atilia 20140930 210755");
//按任意键继续
Console.WriteLine("按任意键继续...");
Console.ReadKey();
Console.WriteLine("\b");
Environment.Exit(0);
}
int counter = 0;
while (true)
{
time_now_a = DateTime.Now.Year * 10000 +
DateTime.Now.Month * 100 + DateTime.Now.Day;
time_now_b = DateTime.Now.Hour * 10000 +
DateTime.Now.Minute * 100 + DateTime.Now.Second;
if (time_now_a < time_a ||
(time_now_a >= time_a && time_now_b < time_b))
{
System.Threading.Thread.Sleep(500);
counter++;
if (counter % 10 == 0)
{
Console.WriteLine("正在等待发信时间 {0} {1}",
time_a, time_b);
counter = 0;
}
}
else
{
break;
}
}
}
//发送邮件
Console.WriteLine("正在发送邮件,请稍候 ...");
smtpclt.Send(mlmssg);
//mail from address must be same as authorization user
//QQ邮箱→设置→账户→POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务
//勾选POP3/SMTP服务
Console.WriteLine("邮件发送完毕,正在释放资源");
smtpclt.Dispose();
mlmssg.Dispose();
Console.WriteLine("按任意键继续...");
Console.ReadKey();
Console.WriteLine("\b");
}
}
}
附:庆祝国庆节的Atilia.html内容
<html>
<head>
<title>
国庆快乐!
</title>
<style>
body{text-align:center}
</style>
</head>
<body>
<span style="color:red;font-size:250%;font-weight:800">
江有汜 携 Atilia 恭祝大家 国庆快乐!!!
</span>
<hr />
<img src="http://upload.wikimedia.org/wikipedia/commons/c/ce/Chinese_flag_%28Beijing%29_-_IMG_1104.jpg"
alt="中华人民共和国国旗" height="400" width="660"/>
<hr>
<b>十一小长假,可要注意好好休息啊~~~</b><br>
<p>
图片来源:
<a href="http://upload.wikimedia.org/wikipedia/commons/c/ce/Chinese_flag_%28Beijing%29_-_IMG_1104.jpg">
维基共享资源:飘扬在北京的五星红旗
</a>
</p>
<p>
程序源码:
<a href="http://my.oschina.net/Tsybius2014/blog/323703">
源码地址
</a>
</p>
刮开涂层赢千万大奖:
<span style="background-color:black;color:black">
Atilia 很萌的,乃们不要黑她 :P
</span>
</body>
</html>
发送后的效果展示:
希望本文所述对大家的C#程序设计有所帮助。


猜你喜欢
- 数组的长度是固定的,无法适应数据变化的需求。为了解决这个问题,Java提供了另一个容器 java.util.ArrayList集合类,让我们
- --删除外键 语法:alter table 表名 drop constraint 外键约束名 如: alter table Stu_PkFk
- 默认情况下,如果应用以 Android Q 为目标平台,则在访问外部存储设备中的文件时会进入过滤视图。应用可以使用 Context.getE
- 本文实例为大家分享了Android实现EventBus登录界面与传值的具体代码,供大家参考,具体内容如下展示效果添加EventBus导入依赖
- 题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x
- 本文实例为大家分享了Android自动播放Banner图片轮播的具体代码,供大家参考,具体内容如下先看一下效果图支持本地图片以及网络图片or
- 一、相关知识SearchView控件:以下是几个简单网址:SearchView简单用法:Android搜索框(SearchView)的功能和
- 我记得最开始接触多进程,多线程这一块的时候我不是怎么理解,为什么要有多线程啊?多线程到底是个什么鬼啊?我一个程序好好的就可以运行为什么要用到
- 在第一次启动项目的时候,由于使用了RabbitMQ的默认guest账号,怎么也登不进去,后来还是在Admin重新创建了一个其他的账号,然后开
- 接收参数的方式:1.HttpServletRequest方式接收public ModelAndView test1(HttpServletR
- 修改加密和验证方法/** * 生成BCryptPasswordEncoder密码 *
- 问题描述:输入:两个日期输出:两个日期相差的天数具体代码实现方法1:通过Calendar类的日期比较。注意:这里需要考虑一下:日期是跨年份的
- ScrollView可实现控件在超出屏幕范围的情况下滚动显示。用法:在XML文件中将需滚动的控件包含在ScrollView中,当控件超出屏幕
- 这篇文章主要介绍了JAVA内存溢出解决方案图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参
- 本文实例为大家分享了android自定义WaveView水波纹控件的使用方法,供大家参考,具体内容如下Github Repository a
- 本文实例讲述了java数据结构与算法之冒泡排序。分享给大家供大家参考,具体如下:前面文章讲述的排序算法都是基于插入类的排序,这篇文章开始介绍
- 某天一朋友突然发来一个地址,问我怎么获取这张图片的后缀名??将代码放在下面以供参考:using System;using System.Dr
- 编写规范目的:能够在编码过程中实现规范化,为以后的程序开发中养成良好的行为习惯。1、 项目名全部小写2、 包名全部小写3、 类名首字母大写,
- java内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类 。在java的世界里,提供了匿名内部类语法,用于帮助大家简化代码,本文
- sql中like通配符模糊匹配问题针对oracle数据库:将查询条件通过功能类处理/** * Desc