。尤其是对于“如何解析EML文件的内容”和 “发送现有的EML文件”。

目前,比较主流的解析EML文件的方式,基本是对MIME格式的分析,基于对 RFC822及其后续扩展的标准 的理解。但是,此种方法工作量太大,且过于繁琐。

我是个懒人,喜欢找捷径

大家都知道,微软的 outlook express 是可以保存和打开并发送EML文件的。那么很明显,outlook express 肯定是可以解析EML文件的。

问题就来了:我们可不可以利用微软现有的成果呢?

针对这个问题,我们再回到.NET中发送邮件的功能上,为了体现的明显,我们回到.NET 1.1上,.NET 1.1 发送邮件的是 System.Web.Mail ,这个System.Web.Mail 当时是比较弱的,原因就是它是基于 cdosys.dll 的基础上的且并未做富实现。

cdosys.dll是从windows 2000 开始被正式引入的,后续的操作系统都支持,关于cdosys.dll的细节,请看MSDN

经过一个晚上对cdosys的研究,终于得出了结果:CDOSYS是可以加载eml文件并进行解析和直接发送的

cdosys属于COM,在.NET使用,需要添加COM引用。

 

添加引用,会在项目的引用里出现下面的2项:

下面我对发送EML文件,封装了一个类(只做了基本封装,大家可以自己扩展)

EML文件发送类  
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->  1
    /**//// <summary>
  2
    /// 功能: 发送EML文件
  3
    /// 作者: 三角猫
  4
    /// 网址: http://www.zu14.cn
  5
    /// 声明: 转载务必保留此信息
  6
    /// </summary>
  7
    public class EmlSender
  8
    
{
  9
        private string emlFilePath;
 10
        private string smtpServer;
 11
        private string smtpServerPort = "25";
 12
        private string smtpUserName;
 13
        private string smtpPassword;
 14
        /**//// <summary>
 15
        /// 构造函数
 16
        /// </summary>
 17
        /// <param name="EmlFilePath">EML文件的绝对路径</param>
 18
        public EmlSender(string EmlFilePath)
 19
        
{
 20
            emlFilePath = EmlFilePath;
 21
        }
 22

 23
        /**//// <summary>
 24
        /// SMTP服务器地址
 25
        /// </summary>
 26
        public string SmtpServer
 27
        
{
 28
            set 
{ smtpServer = value; }
 29
        }
 30

 31
        /**//// <summary>
 32
        /// SMTP服务器端口号
 33
        /// </summary>
 34
        public string SmtpServerPort
 35
        
{
 36
            set 
{ smtpServerPort = value; }
 37
        }
 38

 39
        /**//// <summary>
 40
        /// SMTP服务器认证帐号
 41
        /// </summary>
 42
        public string SmtpUserName
 43
        
{
 44
            set 
{ smtpUserName = value; }
 45
        }
 46

 47
        /**//// <summary>
 48
        /// SMTP服务器认证密码
 49
        /// </summary>
 50
        public string SmtpPassword
 51
        
{
 52
            set 
{ smtpPassword = value; }
 53
        }
 54

 55
        /**//// <summary>
 56
        /// 使用CDOSYS发送EML文件
 57
        /// </summary>
 58
        public void Send()
 59
        
{
 60
            CDO.Message oMsg = new CDO.Message();         
 61
            CDO.IConfiguration iConfg = oMsg.Configuration;
 62
            ADODB.Fields oFields = iConfg.Fields;
 63

 64
            //设置CDO相关的发送参数,主要是用于SMTP服务器的认证
 65
            ADODB.Field oField = oFields["http://schemas.microsoft.com/cdo/configuration/sendusing"];
 66
            oField.Value = "2";
 67

 68
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"];
 69
            oField.Value = smtpServerPort;
 70

 71
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/smtpserver"];
 72
            oField.Value = smtpServer;
 73

 74
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/languagecode"];
 75
            oField.Value = "0x0804";
 76

 77
            //下面三项可以自己根据需要去填写,我比较懒
 78
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/sendemailaddress"];
 79
            oField.Value = "";
 80

 81
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/smtpuserreplyemailaddress"];
 82
            oField.Value = "";
 83

 84
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/smtpaccountname"];
 85
            oField.Value = "";
 86
            //------------------------
 87

 88
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout"];
 89
            oField.Value = "60";
 90

 91
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/sendusername"];
 92
            oField.Value = smtpUserName;
 93

 94
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/sendpassword"];
 95
            oField.Value = smtpPassword;
 96

 97
            oField = oFields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"];
 98
            oField.Value = "1";
 99

100
            oFields.Update();
101

102
            try
103
            
{
104
                //读取EML文件到CDO.MESSAGE,做分析的话,实际是用了下面的部分
105
                ADODB.Stream stm = new ADODB.Stream();
106
                stm.Open(System.Reflection.Missing.Value,
107
                         ADODB.ConnectModeEnum.adModeUnknown,
108
                         ADODB.StreamOpenOptionsEnum.adOpenStreamUnspecified,
109
                         "", "");
110
                stm.Type = ADODB.StreamTypeEnum.adTypeBinary;//二进制方式读入
111

112
                stm.LoadFromFile(emlFilePath); //将EML读入数据流
113

114
                oMsg.DataSource.OpenObject(stm, "_stream"); //将EML数据流载入到CDO.Message,要做解析的话,后面就可以了。
115

116
                stm.Close();
117

118
                oMsg.Send(); //发送
119
            }
120
            catch
121
            
{
122
                throw;
123
            }
124
            finally
125
            
{
126
                oField = null;
127
                oFields = null;
128
                oMsg = null;
129
            }
130
        }
131
    } 
 
 
  使用实例  <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1
EmlSender eml = new EmlSender(@"d:\a.eml");
2
            eml.SmtpServer = "smtp.zu14.cn";
3
            eml.SmtpServerPort = "25";
4
            eml.SmtpUserName = "admin@zu14.cn";
5
            eml.SmtpPassword = "*****";
6
            eml.Send();

至此, 我关于.NET 发送MAIL和保存EML,以及对EML的发送和解析相关的内容, 算是告一段落了。