ASP组件实现Notes新邮件提醒

2013-12-12 10:47:37 电力信息化  点击量: 评论 (0)
中文摘要:通过对Domino数据库进行研究开发,探索Domino数据库如何和企业应用结合,如何能让用户更快了解数据库中未处理邮件数量及内容,反映到企业内部网站上,来达到提高办公工作效率的目的。正文:目前电力系统
中文摘要:
通过对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)
在Domino/Notes的Toolkit中,C/C++的功能是最强大的,能充分利用Domino/Notes已有的功能,修改数据库设计,并能扩展Domino/Notes的能力,对数据的处理能力也是最高的。从将来Domino技术发展来看,IBM公司在Domino/Notes和J2EE平台的结合方面做了不少工作,使用Java/CORBA工具包,用户不必安装Notes客户端就能访问Domino数据库中的绝大部分数据,但Java应用数据处理的速度不高,对Notes数据对象的操纵能力与C/C++工具相比有较大差距。
 
二、新邮件提醒实现方法:
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
大云网官方微信售电那点事儿

责任编辑:和硕涵

免责声明:本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
我要收藏
个赞