C#简单操作Lotus Notes邮件

前段时间简单的研究了一下.NET操作Lotus Notes邮件的实现,具体的操作包括邮件的读取和发送,而且都要包含附件,其间参考了《在 Microsoft .NET 应用程序中使用 IBM Lotus Domino》一文,现在把成果和大家分享一下。

本文将分为获取用户列表、发送邮件、收取邮件三个部分,并会在文末提供范例程序(Visual Studio 2008)的下载。

引用

如果想使用.NET操作Lotus,我们可以使用 Lotus Domino Objects 通过 COM 来访问 Domino 对象,在 Domino 服务器或者任何一个 Notes 客户机(IBM Lotus Domino Designer、Lotus Domino Administrator 或者 Lotus Notes)的安装中都包括 Lotus Domino Objects。如果你的开发环境复合上述的要求,就可以添加一个COM引用:Lotus Domino Objects,然后:

using Domino;

 

如果找不到这个COM组件,可以先注册以下组件,然后就可以找到了:

regsvr32 "C:\Program Files\lotus\notes\nlsxbe.dll"

 

获取Notes邮箱用户列表

本段代码将遍历用户视图(People View)中的所有用户,将其全名添加到ComboBox控件中。新建两个全局变量(全局的目的是供本例中的其它方法使用)。

NotesSession ns;
NotesDatabase ndb;

 

 

发送邮件

本段代码降为从ComboBox中选中的用户发送一封邮件,我们可以输入邮件的标题和内容,并可以添加附件。

try
{
if(ns!=null)
{
NotesDocument doc = ndb.CreateDocument();
doc.ReplaceItemValue(
"Form", "Memo");

//收件人信息
doc.ReplaceItemValue("SendTo", cb_People.Text);

//邮件主题
doc.ReplaceItemValue("Subject", tb_Subject.Text);

//邮件正文
NotesRichTextItem rt = doc.CreateRichTextItem("Body");
rt.AppendText(tb_Body.Text);

//附件
if (!string.IsNullOrEmpty(tb_Attachment.Text))
{
NotesRichTextItem attachment = doc.CreateRichTextItem("attachment");
attachment.EmbedObject(EMBED_TYPE.EMBED_ATTACHMENT, "", tb_Attachment.Text, "attachment");
}

//发送邮件
object obj = doc.GetItemValue("SendTo");
doc.Send(false,ref obj);
doc = null;
MessageBox.Show("Successfully!");
}
}
catch(Exception ex)
{
MessageBox.Show("Error:" + ex.Message);
}

如果想要添加多个收件人,可以将代码:

doc.ReplaceItemValue("SendTo", cb_People.Text);

更改为代码:

 

string[] receivers = { cb_People.SelectedItem.ToString(), "windie chai/TEST" };
doc.ReplaceItemValue("SendTo", receivers);

如果想要添加多个附件,可以继续调用这个对象的EmbedObject方法:

attachment.EmbedObject(EMBED_TYPE.EMBED_ATTACHMENT, "", "FilePath", "attachment");

 

获取收件箱内全部邮件

为了存储邮件内容,我编写了一个简单的类:

///

/// 简单的邮件类
///

public class Mail
{
///

/// 主题
///

public string Subject
{
get { return _subject; }
set { _subject = value; }
}
private string _subject = string.Empty;

///

/// 发件者
///

public string From
{
get { return _from; }
set { _from = value; }
}
private string _from = string.Empty;

///

/// 邮件正文
///

public string Body
{
get { return _body; }
set { _body = value; }
}
private string _body = string.Empty;

///

/// 发件时间
///

public string Time
{
get { return _time; }
set { _time = value; }
}
private string _time = string.Empty;

///

/// 附件集合
///

public List Files
{
get { return _files; }
set { _files = value; }
}
private List _files = new List();
}

接着添加一个全局变量来存储邮件集合:

public List mails = new List();

然后将所有邮件的信息添加的mails集合中,并将它们的标题添加到一个ListBox中。

//清空邮件列表

lb_Mail.Items.Clear();

mails.Clear();

//获取邮箱视图

NotesDbDirectory dir = ns.GetDbDirectory("DominoT/TEST");

NotesDatabase maildb = dir.OpenMailDatabase();

NotesView nv = maildb.GetView("$inbox");

//遍历所有邮件

NotesDocument doc = nv.GetFirstDocument();

while (doc != null)
{
Mail mail = new Mail();
mail.Subject = ((object[])doc.GetItemValue("Subject"))[0].ToString();
mail.From = ((object[])doc.GetItemValue("From"))[0].ToString();
mail.Body = ((object[])doc.GetItemValue("Body"))[0].ToString();
mail.Time = ((object[])doc.GetItemValue("PostedDate"))[0].ToString();
object[] items = (object[])doc.Items;
foreach (NotesItem item in items)
{
if (item.Name == "$FILE")
{
string fileName = ((object[])item.Values)[0].ToString();
NotesEmbeddedObject file = (NotesEmbeddedObject)doc.GetAttachment(fileName);
if (file != null)
mail.Files.Add(file);
}
}
mails.Add(mail);
lb_Mail.Items.Add(mail.Subject);

//查找下一封邮件
doc = nv.GetNextDocument(doc);
}

 

显示邮件内容并打开附件

由于前面的代码中我已经把邮件信息添加到自己定义的邮件集合中了,所以下面的操作就不需要和Domino服务器交互了。

本段代码实现了在ListBox中点击邮件标题后在一个TextBox中显示邮件内容(包括标题,时间,正文和附件文件名)。

Mail m = mails[lb_Mail.SelectedIndex];
StringBuilder sbMail = new StringBuilder();
sbMail.AppendLine(m.Subject);
sbMail.AppendLine("----------");
sbMail.AppendLine(m.Time);
sbMail.AppendLine("----------");
sbMail.AppendLine(m.Body);
sbMail.AppendLine("----------");
sbMail.AppendLine("Attachments:");
foreach (NotesEmbeddedObject file in m.Files)
{
sbMail.AppendLine(file.Name);
}
tb_Mail.Text = sbMail.ToString();

//根据附件数量决定打开附件按钮是否可用
if(m.Files.Count>0)
{
btn_OpenAttachment.Enabled = true;
}
else
btn_OpenAttachment.Enabled = false;

本段代码实现了当点击“打开附件”按钮后从内从中释放附件文件到硬盘并执行它。

Mail m = mails[lb_Mail.SelectedIndex];

//获取第一个附件
NotesEmbeddedObject file = m.Files[0];

//组合一个临时路径
string filename = Path.Combine(Application.StartupPath,file.Name);

//将附件释放到临时路径
file.ExtractFile(filename);

//执行附件
System.Diagnostics.Process.Start(filename);

主要的代码就这么多了,第一次使用IBM的软件,感觉……很不顺手,连对象模型都相当别扭,嗯,废话不说了 ,如果上面的代码有何不恰当的地方还请各位朋友多多指教。

点击这里下载本文的范例程序(Visual Studio 2008),范例程序的UI如下:

点击“Sender”之后回到Notes中,刷新发现邮件已经收到,包含附件,并且可以正常打开:

30 Comments

  1. P.feng

    博主: 请问副本及密送这两��栏位的ItemName应该是什么?谢谢!! //收件人信息 doc.ReplaceItemValue("SendTo", cb_People.Text);试过 doc.ReplaceItemValue("CC", cb_People.Text);或 doc.ReplaceItemValue("BCC", cb_People.Text); 都不行。呵。

  2. P.feng

    自己GOOGLE到了(在BAIDU找了老半天没找到),是:oNotesDocument.ReplaceItemValue("CopyTo", CC); oNotesDocument.ReplaceItemValue("BlindCopyTo", BCC); 谢了!

  3. mylittleflower

    .net里用什么控件可以实现像notes客户端那样的功能?可以把附件拖到邮件的任何一个位置,还可以插入表格、图形、可折叠区段等,总觉得这个很神奇!

  4. yessir

    先高呼一声楼主万岁

    然后请问两个问题:
    1. 是不是可以不要用户名和密码,直接启动默认的邮件客户端
    2. 是否可以不发送,只是打开新邮件发送界面,然后填充信息
    3. 这样发走的邮件会不会保存在已发送邮件里?

  5. yessir

    楼主,你的代码中没有初始化 ns 和 ndb的地方。

    我按你的要求去看了IBM那篇文章,发现他还是需要用密码和domain之类的初始化这两个对象的,请教下。。 如何以dummy方式执行。

    再次感谢

  6. 到最后

    請問是不是只能獲取���前Notes用戶的郵件啊?
    因為我想在不切換ID的情況下,分別獲取兩個Notes帳號中的郵件
    能實現嗎?
    謝謝

  7. @Windie Chai(笑煞天)
    @到最后
    帮你回答下,Notes的邮件都在在邮件数据库中的,邮件数据库和普通的数据库没什么区别,都是.nsf的,只要你能取到该用户
    的邮件数据库就可以取到数据库中的邮件,前提是运行程序的签名要有读文档的权限。

  8. 楼主我在
    NotesDbDirectory dir = ns.GetDbDirectory("DominoT/TEST");
    NotesDatabase maildb = dir.OpenMailDatabase();
    NotesView nv = maildb.GetView("$inbox");
    我程序运行到这里就出错(服务器名改成我自己的),于是我在这段代码这里加了一个try
    {
    NotesDbDirectory dir = ns.GetDbDirectory("DominoT/TEST");
    NotesDatabase maildb = dir.OpenMailDatabase();
    NotesView nv = maildb.GetView("$inbox");
    }
    catch
    {
    MessageBox.Show("Error:" + ex.Message);
    }
    得到database open failed的一个异常,请问楼主能帮忙解决下吗?

  9. TTFocus

    大侠,看了你的文章受益很大。想请教一下:用C#调用Lotus Notes客户端,如果实现自动登录。 我想通过窗口句柄,获取登录窗口并自动输入密码,却没有成功。请问有没有其它办法呢?万分感谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注