标签:
之前的公司一直用outlook,朋友的公司在用IBM的Lotus Notes,找我说希望我帮忙做一个基于Notes的邮件提醒功能。但是无法让公司内IT来协助,也就意味着只能在User的电脑上来处理了。
Google了下,有C#的API,并查到在Notes在安装时会在本地配置文件中写入Server Name及基于当前用户的file。好,开干!
首先需要引入Interop.Domino.dll,这个可以去网上找(240K),也可以直接用NuGet搜Domino。
主要写了两个发邮件的Demo方法,一个仿造网上一个Java的Demo转化为C#的写法(逻辑差不多,只是具体的API名称可能不一致),缺点是样式不方便灵活定制。如下:
/// <summary>
/// Lotus notes email sender.
/// </summary>
/// <param name="mail"></param>
/// <param name="isSupervisor"></param>
static void SendNotesMail(NotesMail mail, bool isSupervisor = false)
{
try
{
NotesSession nSession = new NotesSession();
nSession.Initialize(mail.Password);
NotesDatabase nDatabase = nSession.GetDatabase(mail.ServerName, mail.FileName);
NotesDocument nDocument = nDatabase.CreateDocument();
/*create string variable that will be passed to function. This way we setup To field value*/
//string[] recipients = mail.SendTo;
//setup Form
nDocument.ReplaceItemValue("Form", "Memo");
nDocument.ReplaceItemValue("SendTo", (object)mail.SendTo); //To field
nDocument.ReplaceItemValue("Subject", mail.Subject); //message subject
//nDocument.ReplaceItemValue("Body", mail.Body); //set body text
NotesRichTextItem richTextItem = nDocument.CreateRichTextItem("Body");
richTextItem.AppendText("Hi,");
richTextItem.AddNewLine(2);
if (isSupervisor) {
richTextItem.AppendText("The following is completion of today‘s PCN tasks: ");
} else {
richTextItem.AppendText("The following are the PCN tasks you should comfirm today: ");
}
richTextItem.AddNewLine(2);
// Create table
NotesRichTextParagraphStyle rtps = nSession.CreateRichTextParagraphStyle();
rtps.LeftMargin = 0;
rtps.FirstLineLeftMargin = 0;
rtps.RightMargin = 1;
List<NotesRichTextParagraphStyle> styles = new List<NotesRichTextParagraphStyle>();
for (int i = 0; i < 3; i++) {
styles.Add(rtps);
}
var rowNumber = mail.Body.Length;
var columnNumber = mail.Body[0].ItemArray.Length;
richTextItem.AppendTable(rowNumber, columnNumber);
// Populate table
NotesRichTextNavigator rtnav = richTextItem.CreateNavigator();
rtnav.FindFirstElement(RT_ELEM.RTELEM_TYPE_TABLECELL);
object rtnavo = (object)rtnav;
for (int irow = 1; irow <= rowNumber; irow++) {
for (int icol = 1; icol <= columnNumber; icol++) {
richTextItem.BeginInsert(ref rtnavo);
richTextItem.AppendText(mail.Body[irow-1][icol-1].ToString());
richTextItem.EndInsert();
rtnav.FindNextElement(RT_ELEM.RTELEM_TYPE_TABLECELL);
}
}
nDocument.SaveMessageOnSend = mail.SaveMessageOnSend; //save message after it‘s sent
object oItemValue = nDocument.GetItemValue("SendTo");
nDocument.Send(false, ref oItemValue); //send
}
catch (COMException ex) {
// Let users change their passwords if their passwords have been changed. The better way is using LDAP to check whether the password is correct or not in a windows service.
string logFile = Path.GetFullPath(Path.Combine(logPath, string.Format("{0}.txt", DateTime.Now.ToString("yyyyMMdd"))));
if (ex.Message.Contains("Notes error: Wrong Password")) {
string SecurityToolPath = ConfigurationManager.AppSettings["ChangePasswordToolPath"];
if (!string.IsNullOrEmpty(SecurityToolPath)&&File.Exists(SecurityToolPath)) {
Process.Start(SecurityToolPath);
} else {
Log(logFile, "Password is wrong but serurity tool can not be found. Please check this config file and find the right path of security tool.");
}
}
Log(logFile, ex.Message + Environment.NewLine + ex.StackTrace);
Environment.Exit(0);
}
catch(Exception ex)
{
string logFile = Path.GetFullPath(Path.Combine(logPath, string.Format("{0}.txt", DateTime.Now.ToString("yyyyMMdd"))));
Log(logFile, ex.Message+Environment.NewLine+ex.StackTrace);
Environment.Exit(0);
}
}
第二种方法可以在邮件中定义比较丰富的内容,因为可以使用HTML格式发送邮件。需要说明的是,我为了简便起见,用Word写了个邮件模板,然后转成HTML格式,再将其分成不同的部分(例如Head,Footer,body,Grid等等)保存在txt文档中,发送邮件时利用这些文件拼成一个HTML文档,如下:
/// <summary>
/// Send Notes email using HTML.
/// </summary>
/// <param name="mail"></param>
/// <param name="isSupervisor"></param>
static void SendNotesMailWithHTML(NotesMail mail, bool isSupervisor = false)
{
/* Declare the necessary variables */
NotesSession LNSession = new NotesSession();
NotesDatabase LNDatabase = null;
NotesDocument LNDocument;
NotesMIMEEntity LNMimeRoot;
NotesMIMEEntity LNMime;
NotesMIMEHeader LNHeader;
NotesStream LNStream;
string sMessageBody = string.Empty;
try
{
/* server and username would look similar to the following */
string server = mail.ServerName;
string userName = mail.FileName;
LNSession.Initialize(mail.Password);
/* Since we will be working with MIME entities to create the mail it is important that we turn of the MIME conversion which is turned on by default. */
LNSession.ConvertMime = false;
LNDatabase = LNSession.GetDatabase(server, userName, false);
/* start creating the mail document: */
LNDocument = LNDatabase.CreateDocument();
LNDocument.SaveMessageOnSend = mail.SaveMessageOnSend;
LNDocument.ReplaceItemValue("Form", "Memo");
//LNDocument.ReplaceItemValue("Principal", "System");
/* set the recipients address */
LNDocument.ReplaceItemValue("SendTo", (object)mail.SendTo);
/* create the headers */
LNMimeRoot = LNDocument.CreateMIMEEntity();
LNMime = LNMimeRoot.CreateChildEntity();
LNHeader = LNMimeRoot.GetNthHeader("Content-Type");
LNHeader.SetHeaderVal("multipart/related");
/*
* Subject is defined twice (in the Subject field and MIME header value) since it is possible that the recipient(s)/client(s) can chose
* NOT to display HTML and only show the text part of the mail.
* Hence it is preferable set it in both Subject and MIME header.
*/
LNDocument.ReplaceItemValue("Subject", mail.Subject);
LNHeader = LNMime.CreateHeader("Subject");
LNHeader.SetHeaderVal(mail.Subject);
LNStream = LNSession.CreateStream();
/*
* Build HTML string and attach the HTML body
* A sample HTML string is given below
* NOTE: Some HTML & CSS styles are not rendered properly in some email clients
* RECOMMENDATION: Use basic HTML and Styles
*/
StringBuilder sb = new StringBuilder();
sb.Append(File.ReadAllText(@"C:\Workbench\Dev\NotesEmailHelper\NotesEmailHelperNet2\HTMLDemo\HTMLHeader.txt"));
sb.Append(File.ReadAllText(@"C:\Workbench\Dev\NotesEmailHelper\NotesEmailHelperNet2\HTMLDemo\TableHeader.txt"));
if (isSupervisor) {
sb.AppendFormat(File.ReadAllText(@"C:\Workbench\Dev\NotesEmailHelper\NotesEmailHelperNet2\HTMLDemo\EmailHeader.txt"), "The following is completion of today‘s PCN tasks: ");
} else {
sb.AppendFormat(File.ReadAllText(@"C:\Workbench\Dev\NotesEmailHelper\NotesEmailHelperNet2\HTMLDemo\EmailHeader.txt"), "The following are the PCN tasks you should comfirm today: ");
}
var rowOdd = File.ReadAllText(@"C:\Workbench\Dev\NotesEmailHelper\NotesEmailHelperNet2\HTMLDemo\TableRow1.txt");
var rowEven = File.ReadAllText(@"C:\Workbench\Dev\NotesEmailHelper\NotesEmailHelperNet2\HTMLDemo\TableRow2.txt");
for (int i = 0; i < mail.Body.Length; i++) {
if ((i + 1) % 2 == 0) {
if (mail.Body[i].ItemArray.Length == 14) {
sb.AppendFormat(rowEven, mail.Body[i].ItemArray);
} else {
continue;
}
} else {
if (mail.Body[i].ItemArray.Length == 14) {
sb.AppendFormat(rowOdd, mail.Body[i].ItemArray);
} else {
continue;
}
}
}
sb.Append(File.ReadAllText(@"C:\Workbench\Dev\NotesEmailHelper\NotesEmailHelperNet2\HTMLDemo\HTMLFooter.txt"));
sMessageBody = sb.ToString();
/*
* The imgage source is given as ‘cid:testmail.png‘ .
* It is a marker for the MIME object that it should insert a picture from another MIME object inside the same message.
* Therefore we will need to attach the images as well into MIME objects and here comes a really bad thing when attaching files into a Notesdocument:
* You must have access to the file system and therefore You need to think about a couple of things:
* 1) Is the agent going to be run on the server or locally?
* If You run it only locally - then the picture files must reside on the local computer that runs the agent.
* If You run it scheduled on a server - then the picture must reside on the servers filesystem.
* 2) You must also set the agent security properties to allow restricted operations.
*/
LNStream.WriteText(sMessageBody);
LNMime.SetContentFromText(LNStream, "text/HTML;charset=UTF-8", MIME_ENCODING.ENC_IDENTITY_7BIT);
LNStream.Close();
/* attach the image */
//LNMime = LNMimeRoot.CreateChildEntity();
//LNStream.Open(@"<-Give the exact path to your image->");
/* Note that as the second parameter image type needs to be passed as shown below */
//LNMime.SetContentFromBytes(LNStream, "image/png", MIME_ENCODING.ENC_NONE);
//LNStream.Close();
//LNMime.EncodeContent(MIME_ENCODING.ENC_BASE64);
//LNHeader = LNMime.CreateHeader("Content-ID");
//LNHeader.SetHeaderVal("<- Add here the image source as given in the HTML body. Ex:-testmail.png ->");
/* appending the mail attachment */
//LNMime = LNMimeRoot.CreateChildEntity();
//LNHeader = LNMime.CreateHeader("Content-Disposition");
//LNHeader.SetHeaderValAndParams("attachment; filename=\"<- Enter the file name here ->\"");
//LNStream.Open(@"<- Give the exact path to your image ->", "binary");
//LNMime.SetContentFromBytes(LNStream, "application/octet-stream", MIME_ENCODING.ENC_IDENTITY_BINARY);
//LNMime.EncodeContent(MIME_ENCODING.ENC_BASE64);
//LNStream.Close();
/* send the mail */
LNDocument.Send(false);
LNSession.ConvertMime = true;
}
catch (COMException ex) {
string logFile = Path.GetFullPath(Path.Combine(logPath, string.Format("{0}.txt", DateTime.Now.ToString("yyyyMMdd"))));
if (ex.Message.Contains("Notes error: Wrong Password")) {
string SecurityToolPath = ConfigurationManager.AppSettings["ChangePasswordToolPath"];
if (!string.IsNullOrEmpty(SecurityToolPath)&&File.Exists(SecurityToolPath)) {
Process.Start(SecurityToolPath);
} else {
Log(logFile, "Password is wrong but serurity tool can not be found. Please check this config file and find the right path of security tool.");
}
}
Log(logFile, ex.Message + Environment.NewLine + ex.StackTrace);
Environment.Exit(0);
}
catch(Exception ex)
{
string logFile = Path.GetFullPath(Path.Combine(logPath, string.Format("{0}.txt", DateTime.Now.ToString("yyyyMMdd"))));
Log(logFile, ex.Message+Environment.NewLine+ex.StackTrace);
Environment.Exit(0);
} finally {
/* close all connections */
LNSession = null;
LNDatabase = null;
LNDocument = null;
LNMimeRoot = null;
LNMime = null;
LNStream = null;
LNHeader = null;
}
}
标签:
原文地址:http://www.cnblogs.com/Remote-Shocking/p/5600173.html