标题:
[转帖]谈用Delphi设计Email程序(二)
[打印本页]
作者:
黑白交错
时间:
2005-2-4 16:18
标题:
[转帖]谈用Delphi设计Email程序(二)
[转帖]谈用Delphi设计Email程序(二) 文档名称: 谈用Delphi设计Email程序(二) 文档类别: 原创 文档作者: 陈经韬 lovejingtao@21cn.com 发布日期: 2005年1月27日 文档备注: http://www.138soft.com -------------------------------------------------------------------------------- 谈用Delphi设计Email程序(二) 陈经韬 三:利用ISAPI转发邮件 ISAPI发送邮件的方法跟前面的方法二比较类似.但是也有自己的好处.我以前曾经写过一个转发邮件的Asp,发送内容是没有经过加密的,asp收到数据后存到Access数据库.结果空间被入侵,全部数据被人窥探.因为发送邮件的程序已经安装运行了,所以不可能再去修改其先加密再发送.后来写了一个 ISAPI,把原来的asp文件改成如下内容: <% response.Redirect("jpeg.dll/RecvInfo?Tomail="&request.form("Tomail")&"&mailbody="&request.form("mailbody")) %> 其中jpeg.dll是我写的ISAPI,asp文件直接把收到的数据传递给它,它加密后再存放到Access数据库. 打开Delphi,New-->Web Server Application-->ISAPI/NSAPI Dynamic Link Library,并将工程保存为IsapiMail.dpr.为了发送邮件,我们为单元添加引用IdSMTP和IdMessage,并写了个简单的发送函数: function TWebModule1.My_SendMail(const StrSMTP, StrUser, StrPSW, StrMailFrom, StrMailTo, StrMailSubject, StrMailBody: String): Boolean; var MyIdSMTP: TIdSMTP; MyIdMessage: TIdMessage; begin Result:=False; try MyIdSMTP:=TIdSMTP.Create(nil); MyIdMessage:=TIdMessage.Create(nil); except Exit; end; if MyIdSMTP.Connected then MyIdSMTP.Disconnect; MyIdSMTP.Host:=StrSmtp; MyIdSMTP.Username:=StrUser; MyIdSMTP.Password:=StrPSW; MyIdSMTP.AuthenticationType:=atLogin; MyIdMessage.Body.Clear; MyIdMessage.Body.Text:=StrMailBody; MyIdMessage.From.Text:=StrMailFrom; MyIdMessage.Recipients.EMailAddresses:=StrMailTo; MyIdMessage.Subject:=StrMailSubject; MyIdMessage.ReceiptRecipient.Text := ''; try MyIdSMTP.Connect; except Exit; end; try try MyIdSMTP.Send(MyIdMessage); finally MyIdSMTP.Disconnect; end; except Exit; end; MyIdSMTP.Free; MyIdMessage.Free; Result:=True; end; 回到主窗口,双击WebModule1,出现Editing WebModule1.Actions,新建一个小节WebActionItem1,将其PathInfo改为/SendMail,然后在其OnAction事件写代码: procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var StrSMTP,StrUser,StrPSW,StrMailFrom,StrMailTo,StrMailSubject,StrMailBody: String; begin //依次取的传递进来的参数 StrSMTP:=Request.QueryFields.Values['StrSMTP']; StrUser:=Request.QueryFields.Values['StrUser']; StrPSW:=Request.QueryFields.Values['StrPSW']; StrMailFrom:=Request.QueryFields.Values['StrMailFrom']; StrMailTo:=Request.QueryFields.Values['StrMailTo']; StrMailSubject:=Request.QueryFields.Values['StrMailSubject']; StrMailBody:=Request.QueryFields.Values['StrMailBody']; //调用发送过程 if My_SendMail(StrSMTP,StrUser,StrPSW,StrMailFrom,StrMailTo,StrMailSubject,StrMailBody) then begin Response.Content := '
邮件发送反馈
邮件发送成功!'; Response.Content :=Response.Content +''; end else begin Response.Content := '
邮件发送反馈
邮件发送失败!'; Response.Content :=Response.Content +''; end; end; 编译这个工程得到IsapiMail.dll,然后我们已经可以调用这个dll来发送邮件了.假设该文件的网络路径为http://www.138soft.com/test/IsapiMail.dll(注意:test目录必须有可执行权限),那么我们主要在IE地址栏输入 http://www.138soft.com/test/IsapiMail.dll?StrSMTP=smtp.21cn.com&StrUser=test&StrPSW=1234&StrMailFrom=test@21cn.com&StrMailTo=someone@21cn.com&StrMailSubject=邮件主题&StrMailBody=邮件内容 然后回车,那么页面将返回发送结果. 回到程序设计IDE.可能各位已经注意到WebActionItem1还有几个属性.它们的意义如下: Default:是否为默认小节. Enable:设置为False将不公开接口. MethodType:接收何种方式传递进来的数据. Producer和ProducerContent用于涉及模板时才会用到. 我们再新建一个小节WebActionItem2,将其Default设置为True.然后新建一个包含一jpg图片的资源文件(详见<<谈Delphi中资源文件的利用>>一文).在其事件中写如下代码: procedure TWebModule1.WebModule1WebActionItem2Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var MyRes:TResourceStream; begin {$R jpg.RES} MyRes:=TResourceStream.Create(HInstance,'jpg','jpgfile'); //出于效率考虑,可以放在窗口创建时创建资源.这里暂时每次创建. try Response.SendStream(MyRes); finally MyRes.Free; end; end; 然后我们直接在IE输入http://www.138soft.com/test/IsapiMail.dll,将返回一jpeg图片. 补充: 1:实际上,可以先定义好模版,然后把整个站点封装成为一个dll文件.例如http://www.51delphi.com就是一个范例. 2:为了方便调试ISAPI程序,可以在本机安装一个IIS.不过需要注意的是,ISAPI第一次调用后将常驻内存,在下次重启前该dll文件都无法删除的.这种情况下可以通过暂停IIS再启动来解决.或者直接在cmd状态下IISReset重启IIS.如果还是觉得不方便,那么可以使用Dr.Bob写的 ISAPI Debugger(http://www.drbob42.com/tools/intrabob.htm),不过可惜的是它不支持get方式的调试. -------------------------------------------------------------------------------- 四:自己撰写组件实现email邮件的发送. 我们在第一节已经给出了一个调用Jmail的例子.实际上,我们也可以自己写一个类似的组件. 打开Delphi,选择File--->New--->Other--->Activex--->ActiveX Library 建立一个ActiveX库.保存为MyJMailCom.dpr,然后再File--->New--->Other---> Activex--->Active Server Object,填写类名称,这里我们填写MyJMail.. 菜单View--->Type Library,选中IMyJMail,右键New--->Property.将出现两个Property1,其中一个的Invoke Kind为Property Get,另外一个为Property Put.删除那个Get的,然后把Property1改成SmtpServer,Type改成VARIANT.用同样方法添加SmtpPort(类型为 int),NeedValidate(类型为long),UserName(类型为VARIANT),UserPassword(类型为 VARIANT),MailFrom(类型为VARIANT),MailTo(类型为VARIANT),Subject(类型为VARIANT), Priority(类型为int),ContentType(类型为VARIANT),Charset(类型为VARIANT),Body(类型为 VARIANT),ReplyTo(类型为VARIANT),再添加一个类型为long的变量ResultOK,不过这次是删除Put留下Get.最后新添加一个过程SendEmail. 然后回到单元,我们为工程添加几个私有变量, private strSmtpServer:string; intSmtpPort:integer; intPriority:integer; bNeedValidate,ResultOK:Boolean; strCharset,strContentType:string; strUserName,strUserPassword:string; strMailFrom,strMailTo:string; strSubject,strMsgBody:string; 在COM创建被调入的时候初始化变量: procedure TMyJMail.OnStartPage(const AScriptingContext: IUnknown); begin inherited OnStartPage(AScriptingContext); strSmtpServer:=''; intSmtpPort:=25; intPriority:=3;{mpLowest,mpLow,mpNormal,mpHighest,mpHigh} bNeedValidate:=True; strCharset:=''; strContentType:=''; strUserName:='';strUserPassword:=''; strMailFrom:='';strMailTo:='';strSubject:='';strMsgBody:=''; ResultOK:=False; end; 并填写各属性代码: procedure TMyJMail.Set_NeedValidate(Value: Integer); begin bNeedValidate := Boolean(Value); end; procedure TMyJMail.Set_SmtpPort(Value: SYSINT); begin intSmtpPort := Value; end; procedure TMyJMail.Set_SmtpServer(Value: OleVariant); begin strSmtpServer := Value; end; procedure TMyJMail.Set_UserName(Value: OleVariant); begin strUserName := Value; end; procedure TMyJMail.Set_UserPassword(Value: OleVariant); begin strUserPassword := Value; end; function TMyJMail.Get_ResultOK: Integer; begin Result := Integer(ResultOK); end; procedure TMyJMail.Set_Body(Value: OleVariant); begin strMsgBody := Value; end; procedure TMyJMail.Set_Charset(Value: OleVariant); begin strCharset := Value; end; procedure TMyJMail.Set_ContentType(Value: OleVariant); begin strContentType := Value; end; procedure TMyJMail.Set_MailFrom(Value: OleVariant); begin strMailFrom := Value; end; procedure TMyJMail.Set_MailTo(Value: OleVariant); begin strMailTo := Value; end; procedure TMyJMail.Set_Priority(Value: SYSINT); begin intPriority := Value; end; procedure TMyJMail.Set_Subject(Value: OleVariant); begin strSubject := Value; end; procedure TMyJMail.SendEmail; var MyIdSMTP: TIdSMTP; MyIdMessage: TIdMessage; begin try MyIdSMTP := TIdSMTP.Create(nil); MyIdMessage := TIdMessage.Create(nil); except Exit; end; MyIdSMTP.Host := strSmtpServer; MyIdSMTP.Port := intSmtpPort; if bNeedValidate then MyIdSMTP.AuthenticationType := atLogin else MyIdSMTP.AuthenticationType := atNone; MyIdSMTP.Username := strUserName; MyIdSMTP.Password := strUserPassword; MyIdMessage.CharSet := strCharset; MyIdMessage.ContentType := strContentType; case intPriority of 1: MyIdMessage.Priority := mpLowest; 2: MyIdMessage.Priority := mpLow; 3: MyIdMessage.Priority := mpNormal; 4: MyIdMessage.Priority := mpHigh; 5: MyIdMessage.Priority := mpHighest; else MyIdMessage.Priority := mpNormal; end; MyIdMessage.From.Text := strMailFrom; MyIdMessage.Recipients.EMailAddresses := StrMailTo; MyIdMessage.ReceiptRecipient.Text := ''; MyIdMessage.Subject := strSubject; MyIdMessage.Body.Clear; MyIdMessage.Body.Text := strMsgBody; try MyIdSMTP.Connect; except Exit; end; try MyIdSMTP.Send(MyIdMessage); except MyIdSMTP.Disconnect; MyIdSMTP.Free; MyIdMessage.Free; Exit; end; ResultOK := True; end; 编译此工程,得到MyJMailCom.dll,这个就是我们的COM组件了.在使用之前,必须先注册.直接Regsvr32.exe MyJMailCom.dll即可提示注册成功.(反注册为Regsvr32.exe/u MyJMailCom.dll).我们写一个Asp来测试一下:
邮件发送组件
邮件发送组件
<% Dim MyEmai Set MyEmai = Server.CreateObject("MyJMailCom.MyJMail") MyEmai.SmtpServer="smtp.21cn.com" 'SMTP服务器名称,必须 MyEmai.SmtpPort=25 'SMTP服务器端口.默认为25,可不填 MyEmai.MailFrom="test@21cn.com" '发件人地址,必须 MyEmai.MailTo="someone@21cn.com" '收件人地址,必须 MyEmai.NeedValidate=True 'SMTP服务器是否需要验证用户名称密码.默认为True,可不填 MyEmai.UserName="test" '用户名称,如果需要验证则必须 MyEmai.UserPassword="123456" '用户密码,如果需要验证则必须 MyEmai.Subject="test" '邮件主题 MyEmai.Charset="GB2312" '发送编码.可不填 MyEmai.ContentType ="text" '可不填.若要为htm格式,修改为:XsdEmai.ContentType = "text/html" MyEmai.Priority=3 '是否为紧急邮件(可不填,默认为3).其中1---5分别代表mpLowest,mpLow,mpNormal,mpHighest,mpHigh MyEmai.SendEmail '调用发送过程 if MyEmai.ResultOK then response.write"邮件发送成功!" else response.write"邮件发送失败!" end if %>
补充: 1:用程序注册COM组件的方法如下: type TOleRegister = function : HResult; var hLib : THandle; fnAdr: TFarProc; begin hLib := LoadLibrary(PCHAR(strFileName)); if (hLib > 0) then begin try fnAdr := GetProcAddress(hLib, pchar('DllRegisterServer')) //反注册用fnAdr := GetProcAddress(hLib, pchar('DllUnregisterServer')); if (fnAdr <> nil) then Result := (TOleRegister(fnAdr) >= 0); finally FreeLibrary(hLib); end; 2: 有些COM组件,例如IIS管理组件,因为权限问题,必须先把实现功能部分写成服务(详见<<用Delphi创建服务程序>>).然后再从组件间接调用它.(是否有点象Seru_V?呵呵). -------------------------------------------------------------------------------- 五:其它发送邮件的方法 除了上面的发送方法,还有利用NT服务直接发送特急邮件,MMX发信等.因为有可能导致垃圾邮件发送器的泛滥,此处不再列举.
作者:
黑白交错
时间:
2005-2-4 16:19
标题:
[转帖]谈用Delphi设计Email程序(二)
着帖子为什么着么经典。哈哈!!!
欢迎光临 黑色海岸线论坛 (http://bbs.thysea.com/)
Powered by Discuz! 7.2