准备工作:下载一个OpenPop的插件,OpenPop.dll
这里测试了163邮箱和QQ邮箱,163邮箱直接用账号和授权码就能登录,QQ邮箱需要用SSL验证。
163的服务器是:pop3.163.com , 端口是110
QQ邮箱服务器是:pop.qq.com ,端口是995,需要SSL验证,这段代码没有实现QQ邮箱SSL的验证登陆,非SSL的应该都是没有问题的,后续抽空我会再把SSL的方法贴出来,大家交流学习。
有个问题要提醒大家注意:
1.登录时候只能用第三方授权码登录,而不能用原始密码登录。
2.项目用的是OpenPop.dll 2.0.3版本,从Nuget上下载的OpenPop.dll版本是2.0.6。新版本中已经没有SaveToFile这个方法了,所以程序中SaveToFile方法会报错,需要的可以找我要。目前有两个解决方案:
(1)这个报错的方法是保存邮件附件的方法,不要用的话可以删掉。
(2)在新版本的OpenPop中SaveToFile()方法变成了Save(),直接把程序中的SaveToFile方法替换成Save就好了。
代码里我已经替换掉了(2019/04/25)
由于想要源码的比较多,源码上传QQ群了,群号:需要可私信博主,有需要的可以来下载(2020/09/07)
先上个效果图
代码很简单,你需要和我一样建立4个class,直接上代码:
首先定义接口,说明一下要实现的方法
using OpenPop.Mime;
using OpenPop.Mime.Header;
using OpenPop.Pop3;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Sample.SimpleFactory
{
public abstract class Pop3
{
#region 窗体变量
/// <summary>
/// 是否存在错误
/// </summary>
public abstract Boolean ExitsError { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public abstract String ErrorMessage { get; set; }
/// <summary>
/// POP3端口号
/// </summary>
public abstract Int32 Pop3Port { set; get; }
/// <summary>
/// POP3地址
/// </summary>
public abstract String Pop3Address { set; get; }
/// <summary>
/// 邮箱地址
/// </summary>
public abstract String EmailAddress { set; get; }
/// <summary>
/// 邮箱密码
/// </summary>
public abstract String EmailPassword { set; get; }
#endregion
#region 链接至服务器并读取邮件集合
/// <summary>
/// 链接至服务器并读取邮件集合
/// </summary>
public abstract Boolean Authenticate();
#endregion
#region 获取邮件数量
/// <summary>
/// 获取邮件数量
/// </summary>
/// <returns></returns>
public abstract Int32 GetMailCount();
#endregion
#region 获取发件人
/// <summary>
/// 获取发件人
/// </summary>
/// <param name="mailIndex"></param>
/// <returns></returns>
public abstract String GetSendMialAddress(Int32 mailIndex);
#endregion
#region 获取邮件的主题
/// <summary>
/// 获取邮件的主题
/// </summary>
/// <param name="mailIndex"></param>
/// <returns></returns>
public abstract String GetMailUID(Int32 mailIndex);
#endregion
#region 取邮件的UID
/// <summary>
/// 获取邮件的UID
/// </summary>
/// <param name="mailIndex"></param>
/// <returns></returns>
public abstract String GetMailSubject(Int32 mailIndex);
#endregion
#region 获取邮件正文
/// <summary>
/// 获取邮件正文
/// </summary>
/// <param name="mailIndex">邮件顺序</param>
/// <returns></returns>
public abstract String GetMailBodyAsText(Int32 mailIndex);
#endregion
#region 获取邮件的附件
public abstract Boolean GetMailAttachment(Int32 mailIndex, String receiveBackpath);
#endregion
#region 删除邮件
/// <summary>
/// 删除邮件
/// </summary>
/// <param name="mailIndex"></param>
public abstract void DeleteMail(Int32 mailIndex);
#endregion
#region 关闭邮件服务器
public abstract void Pop3Close();
#endregion
}
}
程序原本包括两种获取邮件的方法,POP3和Lumisoft,
这里就只保留POP3的方法了
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Sample.SimpleFactory
{
public class FactoryPop3
{
public String Pop3Type = "OpenPop";
public Pop3 CreatePop3()
{
Pop3 pop = null;
if (Pop3Type == "OpenPop")
{
return pop = new OpenPopPop3();
}
//else if (Pop3Type == "LumiSoft")
//{
// return pop = new LumiSoftPop3();
//}
else
{
return null;
}
}
}
}
实现接口中虚方法的类
using OpenPop.Mime;
using OpenPop.Mime.Header;
using OpenPop.Pop3;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Sample.SimpleFactory
{
public class OpenPopPop3 : Pop3
{
#region 窗体变量
/// <summary>
/// 是否存在错误
/// </summary>
public override Boolean ExitsError { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public override String ErrorMessage { get; set; }
/// <summary>
/// POP3端口号
/// </summary>
public override Int32 Pop3Port { set; get; }
/// <summary>
/// POP3地址
/// </summary>
public override String Pop3Address { set; get; }
/// <summary>
/// 邮箱地址
/// </summary>
public override String EmailAddress { set; get; }
/// <summary>
/// 邮箱密码
/// </summary>
public override String EmailPassword { set; get; }
#endregion
#region 私有变量
private Pop3Client pop3Client;
// private List<POP3_ClientMessage> pop3MessageList = new List<POP3_ClientMessage>();
private Int32 mailTotalCount;
#endregion
#region 构造函数
public OpenPopPop3() { }
#endregion
#region 链接至服务器并读取邮件集合
/// <summary>
/// 链接至服务器并读取邮件集合
/// </summary>
public override Boolean Authenticate()
{
try
{
pop3Client = new Pop3Client();
if (pop3Client.Connected)
pop3Client.Disconnect();
pop3Client.Connect(Pop3Address, Pop3Port, false);
pop3Client.Authenticate(EmailAddress, EmailPassword, AuthenticationMethod.UsernameAndPassword);
mailTotalCount = pop3Client.GetMessageCount();
return ExitsError = true;
}
catch (Exception ex) { ErrorMessage = ex.Message; return ExitsError = false; }
}
#endregion
#region 获取邮件数量
/// <summary>
/// 获取邮件数量
/// </summary>
/// <returns></returns>
public override Int32 GetMailCount()
{
return mailTotalCount;
}
#endregion
#region 获取发件人
/// <summary>
/// 获取发件人
/// </summary>
/// <param name="mailIndex"></param>
/// <returns></returns>
public override String GetSendMialAddress(Int32 mailIndex)
{
RfcMailAddress address = pop3Client.GetMessageHeaders(mailIndex).From;
return address.Address;
}
#endregion
#region 获取邮件的主题
/// <summary>
/// 获取邮件的主题
/// </summary>
/// <param name="mailIndex"></param>
/// <returns></returns>
public override String GetMailUID(Int32 mailIndex)
{
return pop3Client.GetMessageUid(mailIndex);
}
#endregion
#region 获取邮件的UID
/// <summary>
/// 获取邮件的UID
/// </summary>
/// <param name="mailIndex"></param>
/// <returns></returns>
public override String GetMailSubject(Int32 mailIndex)
{
return pop3Client.GetMessageHeaders(mailIndex).Subject;
}
#endregion
#region 获取邮件正文
/// <summary>
/// 获取邮件正文
/// </summary>
/// <param name="mailIndex">邮件顺序</param>
/// <returns></returns>
public override String GetMailBodyAsText(Int32 mailIndex)
{
Message message = pop3Client.GetMessage(mailIndex);
MessagePart selectedMessagePart = message.MessagePart;
return selectedMessagePart.GetBodyAsText();
}
#endregion
#region 获取邮件的附件
public override Boolean GetMailAttachment(Int32 mailIndex, String receiveBackpath)
{
if (mailIndex == 0)
return false;
else if (mailIndex > mailTotalCount)
return false;
else
{
try
{
Message message = pop3Client.GetMessage(mailIndex);
//邮件的全部附件.
List<MessagePart> attachments = message.FindAllAttachments();
foreach (MessagePart attachment in attachments)
{
string fileName = attachment.FileName;
string fileFullName = receiveBackpath + "\\" + fileName;
FileInfo fileInfo = new FileInfo(fileFullName);
if (fileInfo.Exists) fileInfo.Delete();
attachment.Save(fileInfo);
}
pop3Client.DeleteMessage(mailIndex);
return true;
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
return false;
}
}
return true;
}
#endregion
#region 删除邮件
/// <summary>
/// 删除邮件
/// </summary>
/// <param name="mailIndex"></param>
public override void DeleteMail(Int32 mailIndex)
{
pop3Client.DeleteMessage(mailIndex);
}
#endregion
#region 关闭邮件服务器
public override void Pop3Close()
{
pop3Client.Disconnect();
pop3Client.Dispose();
}
#endregion
}
}
这里是Main函数,代码里可以用循环将所有邮件都取出来,
这里只取第一封邮件演示一下,取出的邮件我放在了DataTable里了,方便查看。
这里测试了163邮箱和QQ邮箱,
163邮箱直接用账号和授权码就能登录,QQ邮箱需要用SSL验证,
163的服务器是:pop3.163.com , 端口是110
QQ邮箱服务器是:pop.qq.com ,端口是995,需要SSL验证,这段代码没有实现QQ邮箱的登陆,后续抽空我会再把SSL的方法贴出来,大家交流学习。
main()
{
FactoryPop3 factory = new FactoryPop3();
Pop3 pop = factory.CreatePop3();
pop.Pop3Port = 110;
pop.Pop3Address = "pop3.163.com";
pop.EmailAddress = "*******@163.com";
pop.EmailPassword = "*******";
pop.Authenticate();
if (pop.ExitsError)
{
DataTable aa = new DataTable();
aa.Columns.Add("MailCount");
aa.Columns.Add("SendMialAddress");
aa.Columns.Add("MailUID");
aa.Columns.Add("MailSubject");
aa.Columns.Add("MailBodyAsText");
DataRow dr = aa.NewRow();
dr["MailCount"] = pop.GetMailCount().ToString();
dr["SendMialAddress"] = pop.GetSendMialAddress(1).ToString();
dr["MailUID"] = pop.GetSendMialAddress(1).ToString();
dr["MailSubject"] = pop.GetSendMialAddress(1).ToString();
dr["MailBodyAsText"] = pop.GetSendMialAddress(1).ToString();
aa.Rows.Add(dr);
//MessageBox.Show(pop.GetMailCount().ToString());
//MessageBox.Show(pop.GetSendMialAddress(1).ToString());
//MessageBox.Show(pop.GetMailUID(1).ToString());
//MessageBox.Show(pop.GetMailSubject(2).ToString());
//MessageBox.Show(pop.GetMailBodyAsText(1).ToString());
}
else
{
//MessageBox.Show(pop.ErrorMessage);
}
}