中文摘要:
通过对Domino数据库进行研究开发,探索Domino数据库如何和企业应用结合,如何能让用户更快了解数据库中未处理邮件数量及内容,反映到企业内部网站上,来达到提高办公工作效率的目的。
正文:
目前电力系统中办公自动化系统使用较多的是Lotus Domino系统,Domino是一个比较独特、比较封闭的非关系数据库管理系统。通过Notes客户端可以安全方便的收发邮件,但是Lotus Notes本身是一种C/S模式程序,在强调系统安全性的同时,给系统管理员和用户带来了不少安装、管理、使用上的麻烦。目前邮件、公文系统使用WEB方式已是大势所趋,本文针对ASP开发环境下对新邮件提醒作一些初步研究,旨在给初学者提供一种思路。
一、了解Notes/Domino的工具包
首先我们需要了解用什么方法可以从外部得到Domino/Notes系统中的数据、对象,Lotus提供了什么样的接口和工具。IBM公司不愧为蓝色巨人,提供了丰富的Notes/Domino的工具包。
二、新邮件提醒实现方法:
1、通过Domino代理写入网关数据库,前台程序例如ASP程序通过数据库接口访问数据库得到新邮件数目。
2、通过Toolkit工具对新邮件进行统计,其中用CAPI实现功能比较强大,几乎可以操作Notes数据库中所有的数据对象(包括数据库及ACL、文档和域、表单、视图、文件夹、代理) 。然后通过ASP程序使用注册的ATL COM组件来取得Notes的未读文档数。
三、准备工作
本文准备利用CAPI新建ATL COM工程来读出Notes未读邮件和总邮件数,开发工具准备选用Visual C++ 7.0,使用Lotus CAPI的应用将根据notes.ini中的信息来得到当前用户的信息,根据查找到的ID文件来验证用户身份。Notes的大部分API都封装在nNotes.dll文件中,其中包括有ACL,Database,User,Document,Item等各个方面的API函数。
在IBM公司网站下载Domino对应版本CAPI,解压至相应目录例如c:\notesapi下,我们这里以Domino5.08举例,打开目录可以看到Include目录和Lib目录,设置好系统变量包括系统路径。
四、编程思路
打开VC++7.0,新建Visual C++项目ATL项目类型,模板选择ATL项目,取名dmnew,设置项目属性添加notes.lib,设置项目VC++项目CAPI包含文件目录和库文件目录,在项目向导里服务器类型选择动态链接库(DLL),添加ATL Active Server Page组件类,取名newmail,其余属性按默认值,在自动生成的Idmnew 接口添加方法getnew([in] BSTR username, [in] BSTR passwd, [out,retval]VARIANT* vOut),
首先需要初始化Notes环境,打开数据库,使用其自动建立的m_piResponse对象可以在ASP页面上输出出错信息,便于调试。
error =NotesInit();
if ( error!=NOERROR)
{
OSLoadString(0, ERR(error), szErrorStr, 256 - 1);
varText.vt = VT_BSTR;
varText.bstrVal = CComBSTR(szErrorStr).Copy();
m_piResponse->Write(varText);
return S_OK;
}
使用SECKFMSwitchToIDFile自动切换到指定的ID,这个API不能支持复杂密码,同时修改Notes.ini相关配置。
error= SECKFMSwitchToIDFile( idfile, idpassword, idUserName, 100, 0, NULL);
根据变量server_name,pathname构成Domino数据库全路径,打开数据库。
error = OSPathNetConstruct(NULL, server_name,pathname,full_netpath);
error=NSFDbOpen(full_netpath, &hDb);//打开数据库
取得指定数据库所有的未读文档列表,同时更新内存中未读文档列表。用户的未读标志存放在客户端的desktop.dsk文件和服务器的数据库,当用户关闭数据库时,客户端和服务器的未读标志会同步。
nameLen=WORD(strlen(zhUserName));
error = NSFDbGetUnreadNoteTable(hDb,zhUserName,nameLen,TRUE,&hTable); error=NSFDbUpdateUnread(hDb,hTable);//
得到数据库中某个视图或文件夹的未读文档数和信息
error=NIFFindDesignNoteByName(hDb,zhViewName,&ViewID);
//取得指定视图或文件夹的所有文档
error=NIFOpenCollection(hDb,hDb,ViewID,0,hTable,&hCollection,NULL,NULL,NULL,NULL);
error=NIFUpdateCollection(hCollection);
利用NIFReadEntries读取文档集的指定文档,再与前面的所有未读文档列表进行一一比较,相同的则是该视图或文件夹的未读文档列表。
CollPosition.Level=0;
CollPosition.Tumbler[0]=0;
//读取文档集的指定文档
error=NIFReadEntries(hCollection,&CollPosition,NAVIGATE_NEXT,1L,NAVIGATE_NEXT,0xFFFF,READ_MASK_NOTEID,&hBuffer,NULL,NULL,&NotesFound,&SignalFlags);
if (hBuffer !=NULLHANDLE)
{ IdList=(NOTEID far *)OSLockObject(hBuffer);
while(IDScan(hTable,fFirst,&NoteID))//依次取得hTable表中的文档号
{ fFirst=FALSE;
for (i=0;i<NotesFound;i++)
if (NoteID==IdList[i])
{ iViewUnread++;
break;
}
}
OSUnlockObject(hBuffer);
OSMemFree(hBuffer);
}
DLL文件中引用m_piResponse对象在ASP页面显示总邮件数目和新邮件数目。
VariantInit(&varText);
varText.vt = VT_I4;
varText.lVal =NotesFound ;
m_piResponse->Write(CComVariant(L"<div align='left' class='black'><font size=2>共有邮件"));
m_piResponse->Write(varText);
m_piResponse->Write(CComVariant(L"封</font></div>"));
varText.lVal =iViewUnread;
m_piResponse->Write(CComVariant(L"<div align='left' class='black'>其中有<b><font color=red size=2>"));
m_piResponse->Write(varText);
m_piResponse->Write(CComVariant(L"</font></b>封新邮件</div>"));
在ASP文件中调用已注册的ATL DLL文件。
dim test
dim retval
set test=Server.CreateObject("dmnew.newmail")
retval=test.getnew("notes文件名","notes密码")
五、涉及问题
1、中文处理
其中Domino牵涉到中文的部分需要进行处理,每个中文字符前面需要加0x13,GB2312编码大约包含6000多汉字(不包括特殊字符),编码范围为第一位b0-f7,第二位编码范围为a1-fe,用以下函数进行处理:
void hangzi_zhuan(char *src,char *des)
{ unsigned char highchar;
unsigned char lowchar;
int l;
int k;
int m;
l=WORD(strlen(src));
for(k= 0,m=0;k<=l;k++,m++)
{
lowchar =( unsigned char)( src[k]);//取源字符串低位
highchar =(unsigned char)(src[k+1]); //取源字符串高位
if ( (highchar>=0xa1) && (highchar<=0xfe) && (lowchar>=0xb0) && (lowchar<=0xf7) )
{
//此字符是汉字
des[m]=0x13;
des[m+1]=lowchar;
des[m+2]=highchar;
k=k+1;
m=m+2;
}
else
{ //此字符不是汉字
des[m]=lowchar;
}
}
}
2、系统变量设置
在系统变量里面设置库文件目录、包含文件目录和系统路径,注意这些路径设置总长度不要超过256个字符,256个字符以后的设置将不会起作用。
3、Domino里面邮件数据库的“收件箱”是一个共享文件夹,它的视图名称为“$Inbox”。
参考文献
Lotus C API 5.0.8 User Guide
Lotus C API 5.0.8 Reference
作者简介
佘世洲(1975年生),男,1997年安徽大学电子工程系本科毕业,工程师。
邮件地址:redbug03@163.com
通讯地址:安徽铜陵供电公司信息中心
邮编:244000
电话:0562-2664404
通过对Domino数据库进行研究开发,探索Domino数据库如何和企业应用结合,如何能让用户更快了解数据库中未处理邮件数量及内容,反映到企业内部网站上,来达到提高办公工作效率的目的。
正文:
目前电力系统中办公自动化系统使用较多的是Lotus Domino系统,Domino是一个比较独特、比较封闭的非关系数据库管理系统。通过Notes客户端可以安全方便的收发邮件,但是Lotus Notes本身是一种C/S模式程序,在强调系统安全性的同时,给系统管理员和用户带来了不少安装、管理、使用上的麻烦。目前邮件、公文系统使用WEB方式已是大势所趋,本文针对ASP开发环境下对新邮件提醒作一些初步研究,旨在给初学者提供一种思路。
一、了解Notes/Domino的工具包
首先我们需要了解用什么方法可以从外部得到Domino/Notes系统中的数据、对象,Lotus提供了什么样的接口和工具。IBM公司不愧为蓝色巨人,提供了丰富的Notes/Domino的工具包。
- Lotus C API toolkit
- Lotus C++ API toolkit
- Lotus Domino Toolkit for Java/CORBA
- Lotus and Notes Toolkit for COM
- Lotus Domino Driver for JDBC (简称LDDJ)
- NotesSQL
- Lotus XML Toolkit(简称DXL)
- Custom Tag Converion kit(简称DCT)
- LotusScript Extensions toolkit(简称LSX)
二、新邮件提醒实现方法:
1、通过Domino代理写入网关数据库,前台程序例如ASP程序通过数据库接口访问数据库得到新邮件数目。
2、通过Toolkit工具对新邮件进行统计,其中用CAPI实现功能比较强大,几乎可以操作Notes数据库中所有的数据对象(包括数据库及ACL、文档和域、表单、视图、文件夹、代理) 。然后通过ASP程序使用注册的ATL COM组件来取得Notes的未读文档数。
三、准备工作
本文准备利用CAPI新建ATL COM工程来读出Notes未读邮件和总邮件数,开发工具准备选用Visual C++ 7.0,使用Lotus CAPI的应用将根据notes.ini中的信息来得到当前用户的信息,根据查找到的ID文件来验证用户身份。Notes的大部分API都封装在nNotes.dll文件中,其中包括有ACL,Database,User,Document,Item等各个方面的API函数。
在IBM公司网站下载Domino对应版本CAPI,解压至相应目录例如c:\notesapi下,我们这里以Domino5.08举例,打开目录可以看到Include目录和Lib目录,设置好系统变量包括系统路径。
四、编程思路
打开VC++7.0,新建Visual C++项目ATL项目类型,模板选择ATL项目,取名dmnew,设置项目属性添加notes.lib,设置项目VC++项目CAPI包含文件目录和库文件目录,在项目向导里服务器类型选择动态链接库(DLL),添加ATL Active Server Page组件类,取名newmail,其余属性按默认值,在自动生成的Idmnew 接口添加方法getnew([in] BSTR username, [in] BSTR passwd, [out,retval]VARIANT* vOut),
首先需要初始化Notes环境,打开数据库,使用其自动建立的m_piResponse对象可以在ASP页面上输出出错信息,便于调试。
error =NotesInit();
if ( error!=NOERROR)
{
OSLoadString(0, ERR(error), szErrorStr, 256 - 1);
varText.vt = VT_BSTR;
varText.bstrVal = CComBSTR(szErrorStr).Copy();
m_piResponse->Write(varText);
return S_OK;
}
使用SECKFMSwitchToIDFile自动切换到指定的ID,这个API不能支持复杂密码,同时修改Notes.ini相关配置。
error= SECKFMSwitchToIDFile( idfile, idpassword, idUserName, 100, 0, NULL);
根据变量server_name,pathname构成Domino数据库全路径,打开数据库。
error = OSPathNetConstruct(NULL, server_name,pathname,full_netpath);
error=NSFDbOpen(full_netpath, &hDb);//打开数据库
取得指定数据库所有的未读文档列表,同时更新内存中未读文档列表。用户的未读标志存放在客户端的desktop.dsk文件和服务器的数据库,当用户关闭数据库时,客户端和服务器的未读标志会同步。
nameLen=WORD(strlen(zhUserName));
error = NSFDbGetUnreadNoteTable(hDb,zhUserName,nameLen,TRUE,&hTable); error=NSFDbUpdateUnread(hDb,hTable);//
得到数据库中某个视图或文件夹的未读文档数和信息
error=NIFFindDesignNoteByName(hDb,zhViewName,&ViewID);
//取得指定视图或文件夹的所有文档
error=NIFOpenCollection(hDb,hDb,ViewID,0,hTable,&hCollection,NULL,NULL,NULL,NULL);
error=NIFUpdateCollection(hCollection);
利用NIFReadEntries读取文档集的指定文档,再与前面的所有未读文档列表进行一一比较,相同的则是该视图或文件夹的未读文档列表。
CollPosition.Level=0;
CollPosition.Tumbler[0]=0;
//读取文档集的指定文档
error=NIFReadEntries(hCollection,&CollPosition,NAVIGATE_NEXT,1L,NAVIGATE_NEXT,0xFFFF,READ_MASK_NOTEID,&hBuffer,NULL,NULL,&NotesFound,&SignalFlags);
if (hBuffer !=NULLHANDLE)
{ IdList=(NOTEID far *)OSLockObject(hBuffer);
while(IDScan(hTable,fFirst,&NoteID))//依次取得hTable表中的文档号
{ fFirst=FALSE;
for (i=0;i<NotesFound;i++)
if (NoteID==IdList[i])
{ iViewUnread++;
break;
}
}
OSUnlockObject(hBuffer);
OSMemFree(hBuffer);
}
DLL文件中引用m_piResponse对象在ASP页面显示总邮件数目和新邮件数目。
VariantInit(&varText);
varText.vt = VT_I4;
varText.lVal =NotesFound ;
m_piResponse->Write(CComVariant(L"<div align='left' class='black'><font size=2>共有邮件"));
m_piResponse->Write(varText);
m_piResponse->Write(CComVariant(L"封</font></div>"));
varText.lVal =iViewUnread;
m_piResponse->Write(CComVariant(L"<div align='left' class='black'>其中有<b><font color=red size=2>"));
m_piResponse->Write(varText);
m_piResponse->Write(CComVariant(L"</font></b>封新邮件</div>"));
在ASP文件中调用已注册的ATL DLL文件。
dim test
dim retval
set test=Server.CreateObject("dmnew.newmail")
retval=test.getnew("notes文件名","notes密码")
五、涉及问题
1、中文处理
其中Domino牵涉到中文的部分需要进行处理,每个中文字符前面需要加0x13,GB2312编码大约包含6000多汉字(不包括特殊字符),编码范围为第一位b0-f7,第二位编码范围为a1-fe,用以下函数进行处理:
void hangzi_zhuan(char *src,char *des)
{ unsigned char highchar;
unsigned char lowchar;
int l;
int k;
int m;
l=WORD(strlen(src));
for(k= 0,m=0;k<=l;k++,m++)
{
lowchar =( unsigned char)( src[k]);//取源字符串低位
highchar =(unsigned char)(src[k+1]); //取源字符串高位
if ( (highchar>=0xa1) && (highchar<=0xfe) && (lowchar>=0xb0) && (lowchar<=0xf7) )
{
//此字符是汉字
des[m]=0x13;
des[m+1]=lowchar;
des[m+2]=highchar;
k=k+1;
m=m+2;
}
else
{ //此字符不是汉字
des[m]=lowchar;
}
}
}
2、系统变量设置
在系统变量里面设置库文件目录、包含文件目录和系统路径,注意这些路径设置总长度不要超过256个字符,256个字符以后的设置将不会起作用。
3、Domino里面邮件数据库的“收件箱”是一个共享文件夹,它的视图名称为“$Inbox”。
参考文献
Lotus C API 5.0.8 User Guide
Lotus C API 5.0.8 Reference
作者简介
佘世洲(1975年生),男,1997年安徽大学电子工程系本科毕业,工程师。
邮件地址:redbug03@163.com
通讯地址:安徽铜陵供电公司信息中心
邮编:244000
电话:0562-2664404