摘要:為應用程式加入寄送 E-mail 的功能(一)
這兩天想要把自己的應用程式加上發送 E-mail 的功能,於是 survey 了幾種方法:
- CDOSYS (Microsoft Collaboration Data Objects for Windows 2000)
- Outlook 提供的 MAPI (Mail Application Programming Interface)
- Indy.NET
CDOSYS 是一個 COM 元件,從 Windows 2000 之後便內建於作業系統,開發人員可以利用此元件來撰寫 E-mail 用戶端程式。若要在 .NET 程式中使用此元件,就必須加入 System.Web.dll 組件參考,這個組件將 CDOSYS COM 元件再包一層,以便讓 .NET 應用程式使用。用法很簡單,參考以下範例程式:
using System.Web.Mail; private void btnSend_Click(object sender, System.EventArgs e) { MailMessage mail = new MailMessage(); mail.From = "huanlin@techshare.com"; // 寄件人 mail.To = "bill@microsoft.com"; // 收件人 mail.Subject = "測試"; // 主旨 mail.Body = "這是一封測試信件"; // 內文 SmtpMail.SmtpServer = "msa.hinet.net"; // SMTP 伺服器位址 SmtpMail.Send(mail); }
但實際測試後發現很容易出問題,例如這個最常見的的錯誤:"無法存取 'CDO.Message' 物件"。由於這個錯誤是由底層的 CDOSYS COM 元件所引發,而 System.Web.dll 並沒有把詳細的錯誤訊息顯示出來,因此往往得費一番手腳找出錯誤的真正原因。我在 Google 上找到相關的系列文章:http://www.systemwebmail.com/faq/4.2.3.aspx。看了這系列的文章之後,決定還是省點麻煩,改用別的方法了。
我試的第二種方法是以 OLE Automation 控制 Outlook 來寄信,做法也很簡單,只要參考下面這篇官方教學文件就可以很快上手:How to use the Microsoft Outlook Object Library to send an HTML formatted message by using Visual C# .NET。使用這種方法有個小缺點,就是是每次寄信時都要建立一個 Outlook 應用程式的 instance,因此需要佔用較多的記憶體資源,且效率上也稍微差了一點。
以上兩種方法都要透過 COM。後來我到網路上尋找別的元件,找到了以前在撰寫 Delphi 程式時常用的 Indy 套件,原來已經有 .NET 版了。Indy 是一套純 .NET 的元件,完全不需要用到 COM 技術,其中包含的 Indy.Sockets 組件就可以用來撰寫 E-mail 程式。不只是 E-mail,這個元件提供了所有跟 sockets 程式設計相關的元件,包括:TCP、UDP、SMTP、POP3、NNTP、HTTP...等。使用也很簡單,例如以下這個寄信的範例程式:
using Indy.Sockets; private void btnSend_Click(object sender, System.EventArgs e) { Indy.Sockets.Message msg = new Indy.Sockets.Message(); // 寄件人 msg.From.Text = txtFrom.Text; // 收件人可以有多個,只要將收件人物件加入 Message 物件的 Recipipients 屬性即可。 EMailAddressItem recipient = msg.Recipients.Add(); recipient.Address = txtTo.Text; // 主旨 msg.Subject = txtSubject.Text; // 內文 msg.Body.Text = txtBody.Text; // 建立 SMTP 物件並設定 SMTP 伺服器位址 SMTP smtp = new SMTP(); smtp.Host = txtSmtpServer.Text; smtp.Connect(); try { smtp.Send(msg); // 送出信件 } finally { smtp.Disconnect(); } }
基本上我還是偏好最後一種方式,一來 Indy 是我之前就用過的元件,品質不錯,而且開放原始碼;二來它是純 .NET 元件,不需要用到 COM。