/*
最近写了一个自动收邮件的机器人,原来一开始偷懒"娶"了 COM 组件 JMail:
《封装 JMail 4.4 的 POP3 为 .Net 组件 (.dll 程序集),实现 "邮件(附件) 到达" 等 "事件"!》
后来经人介绍认识了 OpenPOP.Net
我就移情别恋,再后来我们就相爱了,再后来我就修理她:
加一个小功能(红色字体代码部分),可用于收取邮件时监测数据流量!
老规矩: 我的代码随便 Copy & Paste 到任意一个 .cs 文件中 csc 即可测试! (结构不好,目的就是方便测试代码)
*/
//OpenPOP.Net
namespace OpenPOP.MIMEParser
{
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Globalization;
/// <summary>
/// Summary description for Attachment.
/// </summary>
public class Attachment : IComparable
{
#region Member Variables
private string _contentType = null;
private string _contentCharset = null;
private string _contentFormat = null;
private string _contentTransferEncoding = null;
private string _contentDescription = null;
private string _contentDisposition = null;
private string _contentFileName = "";
private string _defaultFileName = "body.htm";
private string _defaultFileName2 = "body*.htm";
private string _defaultReportFileName = "report.htm";
private string _defaultMIMEFileName = "body.eml";
private string _defaultMSTNEFFileName = "winmail.dat";
private string _contentID = null;
private long _contentLength = 0;
private string _rawAttachment = null;
private bool _inBytes = false;
private byte[] _rawBytes = null;
#endregion
#region Properties
/// <summary>
/// raw attachment content bytes
/// </summary>
public byte[] RawBytes
{
get
{
return _rawBytes;
}
set
{
_rawBytes = value;
}
}
/// <summary>
/// whether attachment is in bytes
/// </summary>
public bool InBytes
{
get
{
return _inBytes;
}
set
{
_inBytes = value;
}
}
/// <summary>
/// Content length
/// </summary>
public long ContentLength
{
get
{
return _contentLength;
}
}
/// <summary>
/// verify the attachment whether it is a real attachment or not
/// </summary>
/// <remarks>this is so far not comprehensive and needs more work to finish</remarks>
public bool NotAttachment
{
get
{
/* if (_contentDisposition==null||_contentType==null)
return true;
else
return (_contentDisposition.IndexOf("attachment")==-1 && _contentType.IndexOf("text/plain")!=-1); */
/* if (_contentType==null)
return true;
else
return (_contentFileName!="");*/
if ((_contentType == null || _contentFileName == "") && _contentID == null) //&&_contentType.ToLower().IndexOf("text/")!=-1)
return true;
else
return false;
}
}
/// <summary>
/// Content format
/// </summary>
public string ContentFormat
{
get
{
return _contentFormat;
}
}
/// <summary>
/// Content charset
/// </summary>
public string ContentCharset
{
get
{
return _contentCharset;
}
}
/// <summary>
/// default file name
/// </summary>
public string DefaultFileName
{
get
{
return _defaultFileName;
}
set
{
_defaultFileName = value;
}
}
/// <summary>
/// default file name 2
/// </summary>
public string DefaultFileName2
{
get
{
return _defaultFileName2;
}
set
{
_defaultFileName2 = value;
}
}
/// <summary>
/// default report file name
/// </summary>
public string DefaultReportFileName
{
get
{
return _defaultReportFileName;
}
set
{
_defaultReportFileName = value;
}
}
/// <summary>
/// default MIME File Name
/// </summary>
public string DefaultMIMEFileName
{
get
{
return _defaultMIMEFileName;
}
set
{
_defaultMIMEFileName = value;
}
}
/// <summary>
/// Content Type
/// </summary>
public string ContentType
{
get
{
return _contentType;
}
}
/// <summary>
/// Content Transfer Encoding
/// </summary>
public string ContentTransferEncoding
{
get
{
return _contentTransferEncoding;
}
}
/// <summary>
/// Content Description
/// </summary>
public string ContentDescription
{
get
{
return _contentDescription;
}
}
/// <summary>
/// Content File Name
/// </summary>
public string ContentFileName
{
get
{
return _contentFileName;
}
set
{
_contentFileName = value;
}
}
/// <summary>
/// Content Disposition
/// </summary>
public string ContentDisposition
{
get
{
return _contentDisposition;
}
}
/// <summary>
/// Content ID
/// </summary>
public string ContentID
{
get
{
return _contentID;
}
}
/// <summary>
/// Raw Attachment
/// </summary>
public string RawAttachment
{
get
{
return _rawAttachment;
}
}
/// <summary>
/// decoded attachment in bytes
/// </summary>
public byte[] DecodedAttachment
{
get
{
return DecodedAsBytes();
}
}
#endregion
/// <summary>
/// release all objects
/// </summary>
~Attachment()
{
_rawBytes = null;
_rawAttachment = null;
}
/// <summary>
/// New Attachment
/// </summary>
/// <param name="bytAttachment">attachment bytes content</param>
/// <param name="lngFileLength">file length</param>
/// <param name="strFileName">file name</param>
/// <param name="strContentType">content type</param>
public Attachment(byte[] bytAttachment, long lngFileLength, string strFileName, string strContentType)
{
_inBytes = true;
_rawBytes = bytAttachment;
_contentLength = lngFileLength;
_contentFileName = strFileName;
_contentType = strContentType;
}
/// <summary>
/// New Attachment
/// </summary>
/// <param name="bytAttachment">attachment bytes content</param>
/// <param name="strFileName">file name</param>
/// <param name="strContentType">content type</param>
public Attachment(byte[] bytAttachment, string strFileName, string strContentType)
{
_inBytes = true;
_rawBytes = bytAttachment;
_contentLength = bytAttachment.Length;
_contentFileName = strFileName;
_contentType = strContentType;
}
/// <summary>
/// New Attachment
/// </summary>
/// <param name="strAttachment">attachment content</param>
/// <param name="strContentType">content type</param>
/// <param name="blnParseHeader">whether only parse the header or not</param>
public Attachment(string strAttachment, string strContentType, bool blnParseHeader)
{
if (!blnParseHeader)
{
_contentFileName = _defaultMSTNEFFileName;
_contentType = strContentType;
}
this.NewAttachment(strAttachment, blnParseHeader);
}
/// <summary>
/// New Attachment
/// </summary>
/// <param name="strAttachment">attachment content</param>
public Attachment(string strAttachment)
{
this.NewAttachment(strAttachment, true);
}
/// <summary>
/// create attachment
/// </summary>
/// <param name="strAttachment">raw attachment text</param>
/// <param name="blnParseHeader">parse header</param>
private void NewAttachment(string strAttachment, bool blnParseHeader)
{
_inBytes = false;
if (strAttachment == null)
throw new ArgumentNullException("strAttachment");
StringReader srReader = new StringReader(strAttachment);
if (blnParseHeader)
{
string strLine = srReader.ReadLine();
while (Utility.IsNotNullTextEx(strLine))
{
ParseHeader(srReader, ref strLine);
if (Utility.IsOrNullTextEx(strLine))
break;
else
strLine = srReader.ReadLine();
}
}
this._rawAttachment = srReader.ReadToEnd();
_contentLength = this._rawAttachment.Length;
}
/// <summary>
/// Parse header fields and set member variables
/// </summary>
/// <param name="srReader">string reader</param>
/// <param name="strLine">header line</param>
private void ParseHeader(StringReader srReader, ref string strLine)
{
string[] array = Utility.GetHeadersValue(strLine); //Regex.Split(strLine,":");
string[] values = Regex.Split(array[1], ";"); //array[1].Split(';');
string strRet = null;
switch (array[0].ToUpper())
{
case "CONTENT-TYPE":
if (values.Length > 0)
_contentType = values[0].Trim();
if (values.Length > 1)
{
_contentCharset = Utility.GetQuotedValue(values[1], "=", "charset");
}
if (values.Length > 2)
{
_contentFormat = Utility.GetQuotedValue(values[2], "=", "format");
}
_contentFileName = Utility.ParseFileName(strLine);
if (_contentFileName == "")
{
strRet = srReader.ReadLine();
if (strRet == "")
{
strLine = "";
break;
}
_contentFileName = Utility.ParseFileName(strLine);
if (_contentFileName == "")
ParseHeader(srReader, ref strRet);
}
break;
case "CONTENT-TRANSFER-ENCODING":
_contentTransferEncoding = Utility.SplitOnSemiColon(array[1])[0].Trim();
break;
case "CONTENT-DESCRIPTION":
_contentDescription = Utility.DecodeText(Utility.SplitOnSemiColon(array[1])[0].Trim());
break;
case "CONTENT-DISPOSITION":
if (values.Length > 0)
_contentDisposition = values[0].Trim();
///<bug>reported by grandepuffo @ https://sourceforge.net/forum/message.php?msg_id=2589759
//_contentFileName=values[1];
if (values.Length > 1)
{
_contentFileName = values[1];
}
else
{
_contentFileName = "";
}
if (_contentFileName == "")
_contentFileName = srReader.ReadLine();
_contentFileName = _contentFileName.Replace("/t", "");
_contentFileName = Utility.GetQuotedValue(_contentFileName, "=", "filename");
_contentFileName = Utility.DecodeText(_contentFileName);
break;
case "CONTENT-ID":
_contentID = Utility.SplitOnSemiColon(array[1])[0].Trim('<').Trim('>');
break;
}
}
/// <summary>
/// verify the encoding
/// </summary>
/// <param name="encoding">encoding to verify</param>
/// <returns>true if encoding</returns>
private bool IsEncoding(string encoding)
{
return _contentTransferEncoding.ToLower().IndexOf(encoding.ToLower()) != -1;
}
/// <summary>
/// Decode the attachment to text
/// </summary>
/// <returns>Decoded attachment text</returns>
public string DecodeAsText()
{
string decodedAttachment = null;
try
{
if (_contentType.ToLower() == "message/rfc822".ToLower())
decodedAttachment = Utility.DecodeText(_rawAttachment);
else if (_contentTransferEncoding != null)
{
decodedAttachment = _rawAttachment;
if (!IsEncoding("7bit"))
{
if (IsEncoding("8bit") && _contentCharset != null & _contentCharset != "")
decodedAttachment = Utility.Change(decodedAttachment, _contentCharset);
if (Utility.IsQuotedPrintable(_contentTransferEncoding))
decodedAttachment = DecodeQP.ConvertHexContent(decodedAttachment);
else if (IsEncoding("8bit"))
decodedAttachment = decodedAttachment;
else
decodedAttachment = Utility.deCodeB64s(Utility.RemoveNonB64(decodedAttachment));
}
}
else if (_contentCharset != null)
decodedAttachment = Utility.Change(_rawAttachment, _contentCharset); //Encoding.Default.GetString(Encoding.GetEncoding(_contentCharset).GetBytes(_rawAttachment));
else
decodedAttachment = _rawAttachment;
}
catch
{
decodedAttachment = _rawAttachment;
}
return decodedAttachment;
}
/// <summary>
/// decode attachment to be a message object
/// </summary>
/// <returns>message</returns>
public Message DecodeAsMessage()
{
bool blnRet = false;
return new Message(ref blnRet, "", false, _rawAttachment, false);
}
/// <summary>
/// Decode the attachment to bytes
/// </summary>
/// <returns>Decoded attachment bytes</returns>
public byte[] DecodedAsBytes()
{
if (_rawAttachment == null)
return null;
if (_contentFileName != "")
{
byte[] decodedBytes = null;
if (_contentType != null && _contentType.ToLower() == "message/rfc822".ToLower())
decodedBytes = Encoding.Default.GetBytes(Utility.DecodeText(_rawAttachment));
else if (_contentTransferEncoding != null)
{
string bytContent = _rawAttachment;
if (!IsEncoding("7bit"))
{
if (IsEncoding("8bit") && _contentCharset != null & _contentCharset != "")
bytContent = Utility.Change(bytContent, _contentCharset);
if (Utility.IsQuotedPrintable(_contentTransferEncoding))
decodedBytes = Encoding.Default.GetBytes(DecodeQP.ConvertHexContent(bytContent));
else if (IsEncoding("8bit"))
decodedBytes = Encoding.Default.GetBytes(bytContent);
else
decodedBytes = Convert.FromBase64String(Utility.RemoveNonB64(bytContent));
}
else
decodedBytes = Encoding.Default.GetBytes(bytContent);
}
else if (_contentCharset != null)
decodedBytes = Encoding.Default.GetBytes(Utility.Change(_rawAttachment, _contentCharset)); //Encoding.Default.GetString(Encoding.GetEncoding(_contentCharset).GetBytes(_rawAttachment));
else
decodedBytes = Encoding.Default.GetBytes(_rawAttachment);
return decodedBytes;
}
else
{
return null;
}
}
public int CompareTo(object attachment)
{
return (this.RawAttachment.CompareTo(((Attachment) (attachment)).RawAttachment));
}
}
public enum MessageImportanceType
{
HIGH = 5,
NORMAL = 3,
LOW = 1
}
/// <summary>
/// Decoding Quoted-Printable text
///
/// </summary>
public class DecodeQP
{
public DecodeQP()
{
}
/// <summary>
/// Decoding Quoted-Printable string
/// </summary>
/// <param name="Hexstring">Quoted-Printable encoded string</param>
/// <param name="encode">encoding method</param>
/// <returns>decoded string</returns>
public static string ConvertHexToString(string Hexstring, string Encoding)
{
try
{
return ConvertHexToString(Hexstring, System.Text.Encoding.GetEncoding(Encoding));
}
catch
{
return ConvertHexContent(Hexstring);
}
}
/// <summary>
/// Decoding Quoted-Printable string
/// </summary>
/// <param name="Hexstring">Quoted-Printable encoded string</param>
/// <param name="encode">encoding method</param>
/// <returns>decoded string</returns>
public static string ConvertHexToString(string Hexstring, Encoding encode)
{
try
{
if (Hexstring == null || Hexstring.Equals("")) return "";
if (Hexstring.StartsWith("=")) Hexstring = Hexstring.Substring(1);
string[] aHex = Hexstring.Split(new char[1] {'='});
byte[] abyte = new Byte[aHex.Length];
for (int i = 0; i < abyte.Length; i++)
{
// Console.WriteLine(aHex[i]);
abyte[i] = (byte) int.Parse(aHex[i], NumberStyles.HexNumber);
}
return encode.GetString(abyte);
}
catch
{
return Hexstring;
}
}
/// <summary>
/// Decoding Quoted-Printable string at a position
/// </summary>
/// <param name="Hexstring">Quoted-Printable encoded string</param>
/// <param name="encode">encoding method, "Default" is suggested</param>
/// <param name="nStart">position to start, normally 0</param>
/// <returns>decoded string</returns>
public static string ConvertHexContent(string Hexstring, Encoding encode, long nStart)
{
if (nStart >= Hexstring.Length) return Hexstring;
//to hold string to be decoded
StringBuilder sbHex = new StringBuilder();
sbHex.Append("");
//to hold decoded string
StringBuilder sbEncoded = new StringBuilder();
sbEncoded.Append("");
//wether we reach Quoted-Printable string
bool isBegin = false;
string temp;
int i = (int) nStart;
while (i < Hexstring.Length)
{
//init next loop
sbHex.Remove(0, sbHex.Length);
isBegin = false;
int count = 0;
while (i < Hexstring.Length)
{
temp = Hexstring.Substring(i, 1); //before reaching Quoted-Printable string, one char at a time
if (temp.StartsWith("="))
{
temp = Hexstring.Substring(i, 3); //get 3 chars
if (temp.EndsWith("/r/n")) //return char
{
if (isBegin && (count%2 == 0))
break;
// sbEncoded.Append("");
i = i + 3;
}
else if (!temp.EndsWith("3D"))
{
sbHex.Append(temp);
isBegin = true; //we reach Quoted-Printable string, put it into buffer
i = i + 3;
count++;
}
else //if it ends with 3D, it is "="
{
if (isBegin && (count%2 == 0)) //wait until even items to handle all character sets
break;
sbEncoded.Append("=");
i = i + 3;
}
}
else
{
if (isBegin) //we have got the how Quoted-Printable string, break it
break;
sbEncoded.Append(temp); //not Quoted-Printable string, put it into buffer
i++;
}
}
//decode Quoted-Printable string
sbEncoded.Append(ConvertHexToString(sbHex.ToString(), encode));
}
return sbEncoded.ToString();
}
/// <summary>
/// Decoding Quoted-Printable string using default encoding and begin at 0
/// </summary>
/// <param name="Hexstring">Quoted-Printable encoded string</param>
/// <returns>decoded string</returns>
public static string ConvertHexContent(string Hexstring)
{
if (Hexstring == null || Hexstring.Equals("")) return Hexstring;
return ConvertHexContent(Hexstring, Encoding.Default, 0);
}
}
/// <summary>
/// Message Parser.
/// </summary>
public class Message
{
#region Member Variables
private ArrayList _attachments = new ArrayList();
private string _rawHeader = null;
private string _rawMessage = null;
private string _rawMessageBody = null;
private int _attachmentCount = 0;
private string _replyTo = null;
private string _replyToEmail = null;
private string _from = null;
private string _fromEmail = null;
private string _date = null;
private string _dateTimeInfo = null;
private string _subject = null;
private string[] _to = new string[0];
private string[] _cc = new string[0];
private string[] _bcc = new string[0];
private ArrayList _keywords = new ArrayList();
private string _contentType = null;
private string _contentCharset = null;
private string _reportType = null;
private string _contentTransferEncoding = null;
private bool _html = false;
private long _contentLength = 0;
private string _contentEncoding = null;
private string _returnPath = null;
private string _mimeVersion = null;
private string _received = null;
private string _importance = null;
private string _messageID = null;
private string _attachmentboundry = null;
private string _attachmentboundry2 = null;
private bool _hasAttachment = false;
private string _dispositionNotificationTo = null;
private ArrayList _messageBody = new ArrayList();
private string _basePath = null;
private bool _autoDecodeMSTNEF = false;
private Hashtable _customHeaders = new Hashtable();
#endregion
#region Properties
/// <summary>
/// custom headers
/// </summary>
public Hashtable CustomHeaders
{
get
{
return _customHeaders;
}
set
{
_customHeaders = value;
}
}
/// <summary>
/// whether auto decoding MS-TNEF attachment files
/// </summary>
public bool AutoDecodeMSTNEF
{
get
{
return _autoDecodeMSTNEF;
}
set
{
_autoDecodeMSTNEF = value;
}
}
/// <summary>
/// path to extract MS-TNEF attachment files
/// </summary>
public string BasePath
{
get
{
return _basePath;
}
set
{
try
{
if (value.EndsWith("//"))
_basePath = value;
else
_basePath = value + "//";
}
catch
{
}
}
}
/// <summary>
/// message keywords
/// </summary>
public ArrayList Keywords
{
get
{
return _keywords;
}
}
/// <summary>
/// disposition notification
/// </summary>
public string DispositionNotificationTo
{
get
{
return _dispositionNotificationTo;
}
}
/// <summary>
/// received server
/// </summary>
public string Received
{
get
{
return _received;
}
}
/// <summary>
/// importance level
/// </summary>
public string Importance
{
get
{
return _importance;
}
}
/// <summary>
/// importance level type
/// </summary>
public MessageImportanceType ImportanceType
{
get
{
switch (_importance.ToUpper())
{
case "5":
case "HIGH":
return MessageImportanceType.HIGH;
case "3":
case "NORMAL":
return MessageImportanceType.NORMAL;
case "1":
case "LOW":
return MessageImportanceType.LOW;
default:
return MessageImportanceType.NORMAL;
}
}
}
/// <summary>
/// Content Charset
/// </summary>
public string ContentCharset
{
get
{
return _contentCharset;
}
}
/// <summary>
/// Content Transfer Encoding
/// </summary>
public string ContentTransferEncoding
{
get
{
return _contentTransferEncoding;
}
}
/// <summary>
/// Message Bodies
/// </summary>
public ArrayList MessageBody
{
get
{
return _messageBody;
}
}
/// <summary>
/// Attachment Boundry
/// </summary>
public string AttachmentBoundry
{
get
{
return _attachmentboundry;
}
}
/// <summary>
/// Alternate Attachment Boundry
/// </summary>
public string AttachmentBoundry2
{
get
{
return _attachmentboundry2;
}
}
/// <summary>
/// Attachment Count
/// </summary>
public int AttachmentCount
{
get
{
return _attachmentCount;
}
}
/// <summary>
/// Attachments
/// </summary>
public ArrayList Attachments
{
get
{
return _attachments;
}
}
/// <summary>
/// CC
/// </summary>
public string[] CC
{
get
{
return _cc;
}
}
/// <summary>
/// BCC
/// </summary>
public string[] BCC
{
get
{
return _bcc;
}
}
/// <summary>
/// TO
/// </summary>
public string[] TO
{
get
{
return _to;
}
}
/// <summary>
/// Content Encoding
/// </summary>
public string ContentEncoding
{
get
{
return _contentEncoding;
}
}
/// <summary>
/// Content Length
/// </summary>
public long ContentLength
{
get
{
return _contentLength;
}
}
/// <summary>
/// Content Type
/// </summary>
public string ContentType
{
get
{
return _contentType;
}
}
/// <summary>
/// Report Type
/// </summary>
public string ReportType
{
get
{
return _reportType;
}
}
/// <summary>
/// HTML
/// </summary>
public bool HTML
{
get
{
return _html;
}
}
/// <summary>
/// Date
/// </summary>
public string Date
{
get
{
return _date;
}
}
/// <summary>
/// DateTime Info
/// </summary>
public string DateTimeInfo
{
get
{
return _dateTimeInfo;
}
}
/// <summary>
/// From name
/// </summary>
public string From
{
get
{
return _from;
}
}
/// <summary>
/// From Email
/// </summary>
public string FromEmail
{
get
{
return _fromEmail;
}
}
/// <summary>
/// Reply to name
/// </summary>
public string ReplyTo
{
get
{
return _replyTo;
}
}
/// <summary>
/// Reply to email
/// </summary>
public string ReplyToEmail
{
get
{
return _replyToEmail;
}
}
/// <summary>
/// whether has attachment
/// </summary>
public bool HasAttachment
{
get
{
return _hasAttachment;
}
}
/// <summary>
/// raw message body
/// </summary>
public string RawMessageBody
{
get
{
return _rawMessageBody;
}
}
/// <summary>
/// Message ID
/// </summary>
public string MessageID
{
get
{
return _messageID;
}
}
/// <summary>
/// MIME version
/// </summary>
public string MimeVersion
{
get
{
return _mimeVersion;
}
}
/// <summary>
/// raw header
/// </summary>
public string RawHeader
{
get
{
return _rawHeader;
}
}
/// <summary>
/// raw message
/// </summary>
public string RawMessage
{
get
{
return _rawMessage;
}
}
/// <summary>
/// return path
/// </summary>
public string ReturnPath
{
get
{
return _returnPath;
}
}
/// <summary>
/// subject
/// </summary>
public string Subject
{
get
{
return _subject;
}
}
#endregion
/// <summary>
/// release all objects
/// </summary>
~Message()
{
_attachments.Clear();
_attachments = null;
_keywords.Clear();
_keywords = null;
_messageBody.Clear();
_messageBody = null;
_customHeaders.Clear();
_customHeaders = null;
}
/// <summary>
/// New Message
/// </summary>
/// <param name="blnFinish">reference for the finishing state</param>
/// <param name="strBasePath">path to extract MS-TNEF attachment files</param>
/// <param name="blnAutoDecodeMSTNEF">whether auto decoding MS-TNEF attachments</param>
/// <param name="blnOnlyHeader">whether only decode the header without body</param>
/// <param name="strEMLFile">file of email content to load from</param>
public Message(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, bool blnOnlyHeader, string strEMLFile)
{
string strMessage = null;
if (Utility.ReadPlainTextFromFile(strEMLFile, ref strMessage))
{
NewMessage(ref blnFinish, strBasePath, blnAutoDecodeMSTNEF, strMessage, blnOnlyHeader);
}
else
blnFinish = true;
}
/// <summary>
/// New Message
/// </summary>
/// <param name="blnFinish">reference for the finishing state</param>
/// <param name="strBasePath">path to extract MS-TNEF attachment files</param>
/// <param name="blnAutoDecodeMSTNEF">whether auto decoding MS-TNEF attachments</param>
/// <param name="strMessage">raw message content</param>
/// <param name="blnOnlyHeader">whether only decode the header without body</param>
public Message(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, string strMessage, bool blnOnlyHeader)
{
NewMessage(ref blnFinish, strBasePath, blnAutoDecodeMSTNEF, strMessage, blnOnlyHeader);
}
/// <summary>
/// New Message
/// </summary>
/// <param name="blnFinish">reference for the finishing state</param>
/// <param name="strMessage">raw message content</param>
/// <param name="blnOnlyHeader">whether only decode the header without body</param>
public Message(ref bool blnFinish, string strMessage, bool blnOnlyHeader)
{
NewMessage(ref blnFinish, "", false, strMessage, blnOnlyHeader);
}
/// <summary>
/// New Message
/// </summary>
/// <param name="blnFinish">reference for the finishing state</param>
/// <param name="strMessage">raw message content</param>
public Message(ref bool blnFinish, string strMessage)
{
NewMessage(ref blnFinish, "", false, strMessage, false);
}
/// <summary>
/// get valid attachment
/// </summary>
/// <param name="intAttachmentNumber">attachment index in the attachments collection</param>
/// <returns>attachment</returns>
public Attachment GetAttachment(int intAttachmentNumber)
{
if (intAttachmentNumber < 0 || intAttachmentNumber > _attachmentCount || intAttachmentNumber > _attachments.Count)
{
Utility.LogError("GetAttachment():attachment not exist");
throw new ArgumentOutOfRangeException("intAttachmentNumber");
}
return (Attachment) _attachments[intAttachmentNumber];
}
/// <summary>
/// New Message
/// </summary>
/// <param name="blnFinish">reference for the finishing state</param>
/// <param name="strBasePath">path to extract MS-TNEF attachment files</param>
/// <param name="blnAutoDecodeMSTNEF">whether auto decoding MS-TNEF attachments</param>
/// <param name="strMessage">raw message content</param>
/// <param name="blnOnlyHeader">whether only decode the header without body</param>
/// <returns>construction result whether successfully new a message</returns>
private bool NewMessage(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, string strMessage, bool blnOnlyHeader)
{
StringReader srdReader = new StringReader(strMessage);
StringBuilder sbdBuilder = new StringBuilder();
_basePath = strBasePath;
_autoDecodeMSTNEF = blnAutoDecodeMSTNEF;
_rawMessage = strMessage;
string strLine = srdReader.ReadLine();
while (Utility.IsNotNullTextEx(strLine))
{
sbdBuilder.Append(strLine + "/r/n");
ParseHeader(sbdBuilder, srdReader, ref strLine);
if (Utility.IsOrNullTextEx(strLine))
break;
else
strLine = srdReader.ReadLine();
}
_rawHeader = sbdBuilder.ToString();
SetAttachmentBoundry2(_rawHeader);
if (_contentLength == 0)
_contentLength = strMessage.Length; //_rawMessageBody.Length;
if (blnOnlyHeader == false)
{
_rawMessageBody = srdReader.ReadToEnd().Trim();
//the auto reply mail by outlook uses ms-tnef format
if ((_hasAttachment == true && _attachmentboundry != null) || MIMETypes.IsMSTNEF(_contentType))
{
set_attachments();
if (this.Attachments.Count > 0)
{
Attachment at = this.GetAttachment(0);
if (at != null && at.NotAttachment)
this.GetMessageBody(at.DecodeAsText());
else
{
}
//in case body parts as text[0] html[1]
if (this.Attachments.Count > 1 && !this.IsReport())
{
at = this.GetAttachment(1);
if (at != null && at.NotAttachment)
this.GetMessageBody(at.DecodeAsText());
else
{
}
}
}
else
{
}
}
else
{
GetMessageBody(_rawMessageBody);
}
}
blnFinish = true;
return true;
}
/// <summary>
/// parse message body
/// </summary>
/// <param name="strBuffer">raw message body</para