2009年12月22日 星期二

使用CDO.Messages來發信,未設定認證(smtpauthenticate)的奇怪現象

基本上使用CDO.Messages來發信,可以選擇使用本機SMTP service或是遠端的SMTP,但我想大多數應該是用遠端的方式吧,畢竟不是每台Sever都有裝SMTP service的

我平常在正式環境使用都是用遠端,然後有啟用基本認證,要輸入帳號密碼後才能寄,這樣幾乎不管到哪裡,程式都能寄信,到目前為止我還沒遇過有問題的,相關程式碼在 http://adalf0722.blogspot.com/2008/12/vbs.html

但有同事也是用遠端,但是是用不需認證的方式寄信,我通常測SMTP service能不能寄信也是用這各測,程式碼如下

Set objEmail = CreateObject("CDO.Message")

objEmail.From = "adalf@test"
objEmail.To = "adalf@test"
objEmail.Subject = "Send the message using the network "
objEmail.Textbody = "(SMTP over the network)"

objEmail.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _
"smtp_server"
objEmail.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objEmail.Configuration.Fields.Update

objEmail.Send

原本我以為這樣的程式碼只適用有安裝SMTP service的電腦上執行,因為那時候同樣的程式碼在我的電腦無法成功,因我的電腦沒裝,而有裝的可以寄信,我就一直這樣認為

最近同事就問我為何有的Server沒裝SMTP service也是能寄呢?跟我原本的想法不一樣,激起我的好奇心,一試下去,不得了,發現奇怪的現象,我試了4台電腦,其中一台有安裝SMTP service,OS為2000 svr,smtpserver都指向它,另外三台都沒裝,OS各為2000 pro,2000 srv與2003 srv,發現svr級的都能寄,pro的不能寄,同樣都是上面的程式碼喔
不能寄2000 pro會出現如下的錯誤訊息
  CDO.Message.1: 該傳輸無法連線到伺服器。

我想該不會是2000 pro不支援吧,光靠那錯誤我並沒有查到有用的資訊,看字面意思是連不到,但我ping ip與telnet ip 25都會通啊,很怪想到我去看smtp的log好了,終於看到一點端倪
那三台可以成功寄信srv留下的
 HELO 250
 MAIL 250
 RCPT 250
 DATA 250
 QUIT 240

那台不能寄信pro留下的
 EHLO 250
 QUIT 240

很怪,為什同樣的程式,在pro與svr下的命令會不同呢?我查一下HELO與EHLO的差別,大概是用EHLO一定要驗證,用HELO不用囉,問題是程式裡並沒有設定到smtpauthenticate啊,我又沒有設定smtpauthenticate為1,0表示不用驗證,1表示基本驗證,真的怪,那我想我在程式中加個一兩行,將smtpauthenticate值秀出來好了,結果在pro的值為1,在svr的值為空值, 為何同樣的程式碼,在不同的環境預設值會不一樣呢?這我真的不知為什,難道srv比較安全預設就不用驗證嗎?

最後經過測試,直接在程式裡指定不要驗證
在objEmail.Configuration.Fields.Update前面加上下面兩行
設定smtpauthenticate與smtpusessl後即可成功發信囉
objEmail.Configuration.Fields.Item _("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 0
objEmail.Configuration.Fields.Item _("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False

@@...最後我還是不知為什...

3 則留言:

  1. 如果 smtp 需用帳號,密碼認證,則 smtpauthenticate 要設為 0
    而且還要再加上

    objEmail.Configuration.Fields.Item _("http://schemas.microsoft.com/cdo/configuration/sendusername") = "USERID" '依實際帳號,此為範例

    objEmail.Configuration.Fields.Item _("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "XXXXXX" '依實際密碼,此為範例

    回覆刪除
    回覆
    1. 需帳號密碼驗證的方式我知道,還是謝謝您的回應

      刪除
    2. 請問, 既然都說需要認證了, 為何還說「如果 smtp 需用帳號,密碼認證,則 smtpauthenticate 要設為 0」? 零不是不驗證的意思嗎?

      刪除