SMTP via GMail

Started by JTaylor, December 09, 2013, 09:40:57 AM

Previous topic - Next topic

JTaylor

Has anyone gotten this example to work via GMail?

http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch/dotNet/System_Net/Mail+Simple~SMTP~Email~Message.txt

I keep getting the "MSCorLib: Exception has been thrown by the target of Invocation." error.

If I use my mail server with the standard port 25 and no SSL it works.  Seems to be a common problem with .NET but not finding a clear answer.


Jim

JTaylor

Of  course now I might have figured it out...

Deana

This worked for me. Notice the use of port 465, and the network credentials:

Code (winbatch) Select
strHost = 'smtp.gmail.com'                                          ;!!!!!!!!! MODIFY TO FIT YOUR NEEDS !!!!!!!!
strTo = 'soandso@here.com'                                      ;!!!!!!!!! MODIFY TO FIT YOUR NEEDS !!!!!!!!
strFrom = 'me@gmail.com'                                     ;!!!!!!!!! MODIFY TO FIT YOUR NEEDS !!!!!!!!
strSubject = 'Sample dotNet Email'                                  ;!!!!!!!!! MODIFY TO FIT YOUR NEEDS !!!!!!!!
strBody = '<HTML><HEADER></HEADER><BODY>Hello World!</BODY></HTML>' ;!!!!!!!!! MODIFY TO FIT YOUR NEEDS !!!!!!!!
strUser = ''                                               ;!!!!!!!!! MODIFY TO FIT YOUR NEEDS !!!!!!!!
strPassword = ''                                            ;!!!!!!!!! MODIFY TO FIT YOUR NEEDS !!!!!!!!
nPort = 465

ObjectClrOption ("use","System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")   
_TRUE = ObjectType( "BOOL", @TRUE )
_FALSE = ObjectType( "BOOL", @FALSE )

NetworkCredential = ObjectClrNew( 'System.Net.NetworkCredential', strUser, strPassword)

MailAddress_From = ObjectClrNew( 'System.Net.Mail.MailAddress', strFrom )
MailAddress_To = ObjectClrNew( 'System.Net.Mail.MailAddress', strTo )

MailMessage = ObjectClrNew( 'System.Net.Mail.MailMessage', MailAddress_From, MailAddress_To )
MailMessage.IsBodyHtml = _True
MailMessage.Subject = strSubject
MailMessage.Body = strBody

SmtpClient = ObjectClrNew( 'System.Net.Mail.SmtpClient' )
SmtpClient.Host = strHost                   ; Specify SMTP Host
SmtpClient.Port = nPort                     ; Port Number
;SmtpClient.UseDefaultCredentials = _TRUE   ; Use SSL
SmtpClient.Credentials = NetworkCredential  ; Authentication
SmtpClient.EnableSsl = _TRUE                ; Use SSL
SmtpClient.Send( MailMessage )              ; Send
exit

Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

If I use port 25 it works but if I use port 465 it doesn't.   I assume you enter a valid user/password and those are not left blank?

Jim

Deana

Quote from: JTaylor on December 09, 2013, 10:04:09 AM
If I use port 25 it works but if I use port 465 it doesn't.   I assume you enter a valid user/password and those are not left blank?

Jim

IF port 25 works for you great... See https://support.google.com/mail/answer/78775?hl=en

Yes of course you must specify a user and password if the mail server requires authentication.
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

Thanks.  Just wanted to make sure I was doing it right since every post I've found on the subject says to use 465.

Jim

stanl

Quote from: JTaylor on December 09, 2013, 12:01:03 PM
Thanks.  Just wanted to make sure I was doing it right since every post I've found on the subject says to use 465.

Jim

Tested Deana's script - using 465 times out, using 25 works.

td

Quote from: stanl on December 10, 2013, 06:07:05 AM
Tested Deana's script - using 465 times out, using 25 works.

Ditto. Got 'Operation timed out' error message with port 465 and worked with port 25.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on December 10, 2013, 07:08:33 AM
Quote from: stanl on December 10, 2013, 06:07:05 AM
Tested Deana's script - using 465 times out, using 25 works.

Ditto. Got 'Operation timed out' error message with port 465 and worked with port 25.

We should probably also test with an attachment.

td

Not surprisingly, port 587 works as well. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

Deana

It appears that code is timing out on me as well, using port 465. I am fairly confident that code worked previously using port 465. Not sure why its timing out now. The google troubleshooting pages indicates...

QuoteIf you tried configuring your SMTP server on port 465 (with SSL) and port 587 (with TLS), but are still having trouble sending mail, try configuring your SMTP to use port 25 (with SSL).

Deana F.
Technical Support
Wilson WindowWare Inc.

td

The Postie extender works with 587 but not with 465. Google probably junked the older 465 SMTPS protocol for MUA access but hasn't updated their docs yet.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor

As usual I have a weird problem or I'm just blind...the test script I modified works, as noted above.   I copied it into my production code and changed a few variable names and now I get the attached error.   Can anyone see what I'm doing wrong?


Code (winbatch) Select
#DefineSubRoutine Send_Mail_DotNet()

  ObjectClrOption ("use","System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")   
  _TRUE                  = ObjectType( "BOOL", @TRUE )
  _FALSE                 = ObjectType( "BOOL", @FALSE )
 
  NetworkCredential      = ObjectClrNew( 'System.Net.NetworkCredential', rqm_user, rqm_pw_word)
 
  MailAddress_From       = ObjectClrNew( 'System.Net.Mail.MailAddress', whofrom )
  MailAddress_To         = ObjectClrNew( 'System.Net.Mail.MailAddress', whoto )
 
  MailMessage            = ObjectClrNew( 'System.Net.Mail.MailMessage', MailAddress_From, MailAddress_To )
  MailMessage.IsBodyHtml = _True
  MailMessage.Subject    = subj
  MailMessage.Body       = msg
 
  SmtpClient             = ObjectClrNew('System.Net.Mail.SmtpClient')
  SmtpClient.Host        = rqm_smtpserver
  SmtpClient.Port        = port
  SmtpClient.Credentials = NetworkCredential  ; Authentication
  SmtpClient.EnableSsl   = _TRUE              ; Use SSL
  SmtpClient.Send(MailMessage)                ; Send

#EndSubRoutine
[/font]
 

JTaylor

Just to be thorough

I changed the test script to match the production code and it still works.
then
I copied the test code to production and it fails
then
I copied the original production code to the test script and it works.

Jim

JTaylor


Deana

Quote from: JTaylor on December 10, 2013, 10:24:12 AM
As usual I have a weird problem or I'm just blind...the test script I modified works, as noted above.   I copied it into my production code and changed a few variable names and now I get the attached error.   Can anyone see what I'm doing wrong?


Code (winbatch) Select
#DefineSubRoutine Send_Mail_DotNet()

  ObjectClrOption ("use","System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")   
  _TRUE                  = ObjectType( "BOOL", @TRUE )
  _FALSE                 = ObjectType( "BOOL", @FALSE )
 
  NetworkCredential      = ObjectClrNew( 'System.Net.NetworkCredential', rqm_user, rqm_pw_word)
 
  MailAddress_From       = ObjectClrNew( 'System.Net.Mail.MailAddress', whofrom )
  MailAddress_To         = ObjectClrNew( 'System.Net.Mail.MailAddress', whoto )
 
  MailMessage            = ObjectClrNew( 'System.Net.Mail.MailMessage', MailAddress_From, MailAddress_To )
  MailMessage.IsBodyHtml = _True
  MailMessage.Subject    = subj
  MailMessage.Body       = msg
 
  SmtpClient             = ObjectClrNew('System.Net.Mail.SmtpClient')
  SmtpClient.Host        = rqm_smtpserver
  SmtpClient.Port        = port
  SmtpClient.Credentials = NetworkCredential  ; Authentication
  SmtpClient.EnableSsl   = _TRUE              ; Use SSL
  SmtpClient.Send(MailMessage)                ; Send

#EndSubRoutine
[/font]


?? The code you posted indicates the line is

Code (winbatch) Select
SmtpClient.Port        = port

Yet the error message indicates

Code (winbatch) Select
SmtpClient.Port        = nport

Notice nPort in the error message. Try using DebugTrace with the production code. Is suspect that you will find the issue when you inspect the trace file.
Deana F.
Technical Support
Wilson WindowWare Inc.

Deana

Also apparently the Port property is only available on .NET Framework version 2.0 and newer.  Is your production code possibly on a system with only a very old version of the framework?

http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.port(v=vs.110).aspx
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

No.  I have 4.5 installed and as I mentioned.  If I run the same code in its own script it runs.  If I copy it into my program it fails with that error.

Jim

Deana

Quote from: JTaylor on December 10, 2013, 01:42:28 PM
No.  I have 4.5 installed and as I mentioned.  If I run the same code in its own script it runs.  If I copy it into my program it fails with that error.

Jim

The code you posted and the errorline do not match. Time to use debugtrace.
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

Of course not, that part of the program is 1323 lines but didn't think you wanted all of that.   The line # is the one report by the error message.  I can run debug trace though.

Jim

Deana

I am not referring to the line number. I am referring to the actual line of code.  Specifically the variable name nPort vs Port.

You do not need to debug the entire production script, just the UDS. See the WIL help file for details about all the debugging options offered by the DebugTrace function.
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

I sent the Trace directly in case there is stuff in there I don't want to make public.   I think the port/nport difference was just me trying different things and my posts were out of sync.

Thanks.

Jim

Deana

Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

Ditto....and for everyone else....adding zero to the port number seems to have fixed the problem.

Thanks.

Jim

JTaylor

Is there a way to trap the "Exceptions"?   Currently it seems if anything is wrong such as a server address or such thing it throws a very unhelpful error and crashes the script.  I was trying something like:

  SmtpEx                 = ObjectClrNew( 'System.Net.Mail.SmtpFailedRecipientsException' )
  rc = SmtpEx.StatusCode

But, of course, this isn't helpful since the error would have already crashed the script.

Thanks.

Jim

Deana

Quote from: JTaylor on December 10, 2013, 05:12:19 PM
Ditto....and for everyone else....adding zero to the port number seems to have fixed the problem.

Thanks.

Jim

Interesting. It is not at all clear to me how simply appending a zero to the port number would resolve the issue. 

As I understand it, the extended error returned is simply returned by the underlying CLR engine.

Just curious...What made you think to add the zero in the first place?

I suppose its possible it could be a data type issue. What function did you use to append the zero?

Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

I meant Adding, as in Addition (ex.   port = port + 0)

I was trying to figure out what was different between my test and production code.   Stripping extraneous code didn't seem to make a difference but supplying the mail info directly as in my test code worked.  That is...

  port = 25

worked.   

Pulling it from my database did not.   I've run into this type of problem with COM stuff before so thought maybe it wasn't seeing it as a number and tried forcing the issue with Addition.

Okay on the Error.  Was hoping there was a way to get useful error info and recover gracefully.  Can do the graceful recovery part but would be nice to know what the problem actually was so I could report it to the user.

Jim

Deana

I recommend using the ObjectType function to insure you are passing the proper data type.

The documentation for the Port property indicates it expects the following data type:

Quote
Property Value
Type: System.Int32
An Int32 that contains the port number on the SMTP host. The default value is 25.
http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.port(v=vs.110).aspx

To enforce this data type in WinBatch you would use:

Code (winbatch) Select

port_value = ObjectType( 'I4', 25 ) ;Creates a WIL variable with an I4/Int32 COM/OLE variant type.
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor


Deana

Quote from: JTaylor on December 11, 2013, 09:06:59 AM
Thanks again.

So no way to trap these Exceptions?

http://msdn.microsoft.com/en-us/library/swas0fwc%28v=vs.110%29.aspx


Jim

You can trap errors in WinBatch using IntControl 73. The "additional error information" (in the case of CLR the exception) can be obtained using the wberroradditionalinfo variable defined when an error occurs. For more about error handling in WinBatch please read:  http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+Tutorials+Trap~Errors.txt
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

Guess I should try it before asking but since I think I know the answer...will the error be the "Exception....target of invocation" message like I see in WinBatch ( I assume so) or something actually useful?   I'd like to know the problem like I can with the Postie Extender.

Jim

Deana

Quote from: JTaylor on December 11, 2013, 09:58:25 AM
Guess I should try it before asking but since I think I know the answer...will the error be the "Exception....target of invocation" message like I see in WinBatch ( I assume so) or something actually useful?   I'd like to know the problem like I can with the Postie Extender.

Jim

You will get the same information you got when it errored in WinBatch.

Including the Extended error information:

Quote[COM/CLR Exception]
mscorlib=Method 'System.Net.Mail.SmtpClient.Port' not found.
[COM & CLR Sub-system]
Function=InvokeMember
ErrorCode=5394 (0x80131512)
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

So, is the answer to my question about being able to trap the "Exceptions" "No"?      I know how to trap Errors in Winbatch but for the problems I'm talking about that is not helpful as the WinBatch Error is useless.  In the case you reference it is worse than useless as it is misleading but that is really a different issue.  If a message fails to send it would be helpful to know why.   Just like in Postie when a messages fails to send knowing that the send response is "0" isn't very helpful in solving the problem but  kStatusInfo() can be very enlightening.

Jim

Deana

Quote from: JTaylor on December 11, 2013, 11:27:22 AM
So, is the answer to my question about being able to trap the "Exceptions" "No"?      I know how to trap Errors in Winbatch but for the problems I'm talking about that is not helpful as the WinBatch Error is useless.  In the case you reference it is worse than useless as it is misleading but that is really a different issue.  If a message fails to send it would be helpful to know why.   Just like in Postie when a messages fails to send knowing that the send response is "0" isn't very helpful in solving the problem but  kStatusInfo() can be very enlightening.

Jim

Actually the answer is yes. I thought I was clear....The additional error information is the exception returned from the CLR engine.

You have to understand that Extender errors and Errors returned from the CLR are two very different animals.

Unfortunately useless error messages in Windows is nothing new.
Deana F.
Technical Support
Wilson WindowWare Inc.

JTaylor

Guess I'm just being dense so I apologize but I'm still not seeing it.   Attached are three examples of errors with the WinBatch error information.  The file names are explanatory.  Based on the error info provided how would I know the real problem?

Jim