viewpoint-particle

Author Topic: Send email via SMTP example using .net  (Read 236 times)

Jeff

  • Newbie
  • *
  • Posts: 11
Send email via SMTP example using .net
« on: November 29, 2017, 12:40:32 pm »
Does anyone have an example of sending an email via SMTP example using .net?
Jeff

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


Jeff

  • Newbie
  • *
  • Posts: 11
Re: Send email via SMTP example using .net
« Reply #2 on: November 30, 2017, 11:40:39 am »
How do you capture an error from this sample? In samples I see there is a "try/catch". But I don't think it's applicable in WB.

try {

client.Send(message);

}

catch (Exception ex) {

Console.WriteLine("Exception caught in CreateTestMessage2(): {0}",

ex.ToString() );

}

}


One last question, does anyone have an example of sending an email via Exchange Web Service?

Thanks.
Jeff

stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #3 on: November 30, 2017, 01:36:06 pm »
Are you asking for code for an Internal Exchange Server w/out Outlook - or Web Mail.  Because I think with Exchange you just need to access system.Net.Mail.SmtpClient and system.Net.NetworkCredential. But that being said, we tried it from our corporate headquarters and it gets squashed by IT security. A co-worker discovered a way to break through with VB NET but it relies on a third party dll.

JTaylor

  • Pundit
  • *****
  • Posts: 804
    • Data & Stuff Inc.
Re: Send email via SMTP example using .net
« Reply #4 on: November 30, 2017, 06:55:18 pm »
Not sure if it would see a .NET attempt via WinBatch the same as the Postie but probably close enough...if so, as Stan noted, you will have to have your email administrator configure the server to allow the messages.  By default it blocks such messages.

Jim

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #5 on: December 01, 2017, 06:34:53 am »
How do you capture an error from this sample? In samples I see there is a "try/catch". But I don't think it's applicable in WB.

try {

client.Send(message);

}

catch (Exception ex) {

Console.WriteLine("Exception caught in CreateTestMessage2(): {0}",

ex.ToString() );

}

}

You use WinBatch's built in error handling as try-catch block exception handling is a property of the language not the dotNet  framework.   See IntControl 73 in the Consolidated WIL Help file for details.
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #6 on: December 01, 2017, 06:55:31 am »

One last question, does anyone have an example of sending an email via Exchange Web Service?


Apparently not.  Not sure if this is what you are referring to but MSFT's Exchange Web Services has it's own managed assembly - Microsoft.Exchange.WebServices (in Microsoft.Exchange.WebServices.dll) -  and I am not aware of any examples in the Tech Database.  MSFT does have extensive documentation of the assembly on their MSDN Website.  A quick glance does not reveal anything that you counldn't do using the WinBatch CLR hosting functionality.   I guess this would be your chance to break new ground for the rest of us.
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #7 on: December 01, 2017, 12:46:16 pm »
I tried that with a simple powershell script to send a test message. It fails with the AutodiscoverUrl method again saying it is blocked as an insecure redirection. If I manually attempt to access the url

https://autodiscover.[mydomain].com/autodiscover/autodiscover.xml it returns 'invalid request' (even after entering my credentials).

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #8 on: December 01, 2017, 01:20:43 pm »
If you are talking about SMTP then I believe Jim already covered that ground.  If you are talking about MSFT's EWS API, I am not at all familiar with it but it should work if used properly.  MSFT has examples in their documentation that wouldn't be their if they didn't think it works.
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #9 on: December 02, 2017, 03:21:19 am »
If you are talking about SMTP then I believe Jim already covered that ground.  If you are talking about MSFT's EWS API, I am not at all familiar with it but it should work if used properly.  MSFT has examples in their documentation that wouldn't be their if they didn't think it works.

Agreed. But some context is important. From my job, logged into the corporate network, I can automate emails from either my google or mindspring accounts, but not from my Outlook/Exchange given corporate security measures. The AutodiscoverUrl method I referred to in my last post has a second parameter, a delegate callback - and the WB CLR does not do delegates. But for the general purpose of this thread, below is the simple Powershell steps (which can be interpreted into WB CLR, or called directly from it)

Code: [Select]
Add-Type -Path "C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll"


$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1)

$service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList  [email address], “[Password]”
$service.AutodiscoverUrl('[email address]', '{@True}')
$message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service
$message.Subject = 'Test is a test'
$message.Body = 'This message is being sent through EWS with PowerShell'
$message.ToRecipients.Add(‘[recipient]')
$message.SendAndSaveCopy()


so it really isn't that hard - if it works.

JTaylor

  • Pundit
  • *****
  • Posts: 804
    • Data & Stuff Inc.
Re: Send email via SMTP example using .net
« Reply #10 on: December 02, 2017, 06:20:43 am »
Sounds like the issue is what I mentioned.   The Server knows if you are not a "secure" client and it will block any attempt by anything other than the Exchange/Outlook client, unless explicitly permitted.   I don't think it will matter what method you attempt to use.   

Jim

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #11 on: December 02, 2017, 07:57:28 am »
That begs the question - what constitutes a secure client?  The server has to recognize something in the exchange between client and server to permit an action.  If it isn't just credentials then what is it?  A user agent string?  A quick reading of the documentation seems to suggest that the correct user-agent string and, of course,  credentials are all that are needed.  If that is the case then the it would just be a matter of getting someone with server admin privileges to add the script's user agent string to an "approved" list.   Another option would be to somehow spoof the scripts user agent string so that it matched an approved user agent string. 

MSFT's EWS documentation makes much of the distinction between authentication and authorization.   Authentication is provided by either NTLM or OAuth.  NTLM requires a domain connection and is supported by dotNet.  But this is likely a different discussion.

"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #12 on: December 02, 2017, 02:07:48 pm »

Agreed. But some context is important. From my job, logged into the corporate network, I can automate emails from either my google or mindspring accounts, but not from my Outlook/Exchange given corporate security measures. The AutodiscoverUrl method I referred to in my last post has a second parameter, a delegate callback - and the WB CLR does not do delegates. But for the general purpose of this thread, below is the simple Powershell steps (which can be interpreted into WB CLR, or called directly from it)

The  AutodiscoverUrl method has two signatures with only one requiring a delegate so the method is usable in a WIL script.

Quote
so it really isn't that hard - if it works.

It is quite simple.   Simpler than I had imaged.  It should easily convert to a WIL script.  A converted and tested WIL script example would make a nice addition to the Tech Database.

 
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #13 on: December 02, 2017, 04:50:25 pm »

It is quite simple.   Simpler than I had imaged.  It should easily convert to a WIL script.  A converted and tested WIL script example would make a nice addition to the Tech Database.

And I would be willing to test and report back specific security errors.

stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #14 on: December 03, 2017, 04:13:45 am »
OMG! Thank you Tony.   I removed the second parameter in the Powershell script:

Code: [Select]
$service.AutodiscoverUrl('[email address]',)

and it worked perfectly. Seems if I knew what I was doing in the first place, I wouldn't need an overloaded callback.   :o

EDIT:

Quote
It should easily convert to a WIL script

Yeah, wish I had time, but need to expand the basic PS script to handle delayed posting. Also not sure about the initial namespace.


td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #15 on: December 05, 2017, 07:44:20 am »
Here is a very rough translation to WIL script.  Needs a lot of work but may be of use to the original poster as a starting point for a 'real' script.

Code: Winbatch
;; Completely untested, full of bugs and guaranteed to fail.
ObjectClrOption('appbase', 'C:\Program Files (x86)\Microsoft\Exchange\Web Services\2')
ObjectClrOption('use', 'Microsoft.Exchange.WebServices')

enumVersion = ObjectType('Microsoft.Exchange.WebServices.Data.ExchangeVersion', some number here)  ; Need the assembly to find version number
objEws = ObjectCreate(' Microsoft.Exchange.WebServices.Data.ExchangeService', emumVersion)

objEws.Credentials = ObjectCreate('Microsoft.Exchange.WebServices.Data.WebCredentials', '[email address]', '[Password]')
objEws.AutodiscoverUrl('[email address]')
objMessage = ObjectCreate('Microsoft.Exchange.WebServices.Data.EmailMessage', objEws)
objMessage.Subject = 'Test is a test'
objMessage.Body = 'This message is being sent through EWS with WinBatch CLR hosting'
objMessage.ToRecipients.Add('[recipient]')
objMessage.SendAndSaveCopy()

 
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #16 on: December 05, 2017, 10:30:32 am »
Nice.... I changed to

Code: Winbatch
ObjectClrOption('useany', 'Microsoft.Exchange.WebServices')
 

and found the version number by holding ctrl, right clicking on Outlook icon in notification area then clicking connection status. Should have results of test later today.

[EDIT]  my version is 15.0.1104.4000  but the line   [where nVersion = 15.0.1104

Code: Winbatch
oVersion = ObjectType('Microsoft.Exchange.WebServices.Data.ExchangeVersion', nVersion)
 

gives error as unsupported Variant Type.

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #17 on: December 05, 2017, 10:44:49 am »
Generally, you only need to use the 'useany' option when the assembly resides in the GAC but it doesn't hurt in this case.

Looks like one of my many typos.  Try something like this:

Code: Winbatch
enumVersion = ObjectClrType('Microsoft.Exchange.WebServices.Data.ExchangeVersion', '15.0.1104.4000')
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #18 on: December 05, 2017, 11:10:06 am »
getting closer

Code: Winbatch
oVersion = ObjectClrType('Microsoft.Exchange.WebServices.Data.ExchangeVersion','15.0.1104.4000' ) ;works now
oEws = ObjectCreate(' Microsoft.Exchange.WebServices.Data.ExchangeService', oVersion) ; error as invalid class string

 

[EDIT]

Probably should be ObjectClrNew

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #19 on: December 05, 2017, 11:46:35 am »
"Microsoft.Exchange.WebServices.Data.ExchangeVersion" so it is likely and integer value.  So the version passed as a constructor parameter might simply be the number 7 except that is is cast as the enumeration "Microsoft.Exchange.WebServices.Data.ExchangeVersion" so that the CLR knows which constructor to call.   So an alternative may be the following:

Code: Winbatch
enumVersion = ObjectClrNew('Microsoft.Exchange.WebServices.Data.ExchangeVersion')
curVersion   = ObjectClrType('Microsoft.Exchange.WebServices.Data.ExchangeVersion',enumVersion.Exchange2013_SP1)
oEws = ObjectCreate('Microsoft.Exchange.WebServices.Data.ExchangeService', curVersion) ;

Where the supported version are listed as:

        Exchange2007_SP1   - Exchange Server 2007 Service Pack 1 (SP1).
        Exchange2010    - Exchange Server 2010.
        Exchange2010_SP1   - Exchange Server 2010 Service Pack 1 (SP1).
        Exchange2010_SP2   - Exchange Server 2010 Service Pack 2 (SP2).
        Exchange2013   - Exchange Server 2013.
        Exchange2013_SP1   - Exchange Server 2013 Service Pack 1 (SP1).

I would also be wise to remove the lead space from ' Microsoft.Exchange.WebServices.Data.ExchangeService' .
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #20 on: December 05, 2017, 12:01:47 pm »
OK. Down to the wire,  I'm using an INI file to hold values but this works now up to

Code: Winbatch
ObjectClrOption('appbase', cDLL)
ObjectClrOption('useany', 'Microsoft.Exchange.WebServices')
oEws = ObjectClrNew('Microsoft.Exchange.WebServices.Data.ExchangeService')
oVersion = ObjectClrType('Microsoft.Exchange.WebServices.Data.ExchangeVersion', nVersion )

oEws.Credentials = ObjectClrNew('Microsoft.Exchange.WebServices.Data.WebCredentials', cEmail, cPwd)
oEws.AutodiscoverUrl(cEmail)
oMessage = ObjectClrNew('Microsoft.Exchange.WebServices.Data.EmailMessage', oEws)
oMessage.Subject = 'Test is a test'

oMessage.Body = 'This message is being sent through EWS with WinBatch CLR hosting'  ;Error - see attached jpeg
                                                                                                                                ;comment line out and script will send message w/out body

oMessage.ToRecipients.Add('slittlefield1@gmail.com')
oMessage.SendAndSaveCopy()


 

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #21 on: December 05, 2017, 01:34:21 pm »
First, an apology for getting sloppy with regard to the enumeration.  I know better but was trying to do too many things as once.

It appears that the "Body" method is actually a class object.  So it needs to be constructed somehow.  Maybe

Code: Winbatch
objBody = ObjectCreate('Microsoft.Exchange.WebServices.Data.MessageBody', 'This message is being sent through EWS with WinBatch CLR hosting')
objMessage.Body = objBody
 

It is just a shot in the dark but it might work.  If it doesn't, it may be because the name space isn't quit right or the constructor parameter needs to be typed using ObjectClrType.  For whatever reasons the CLR is a bit inconsistent about these things.
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #22 on: December 05, 2017, 05:38:58 pm »
This worked. Parameters are in the INI file, but script is adaptable. I used the body object text, as there is a bodytype that takes text or HTML.

Code: Winbatch
IntControl(73,1,0,0,0)
cINI=DirScript():"ews.ini"
If ! FileExist(cINI) Then Terminate(@TRUE,"Cannot Continue","Configuration File Is Missing ":cINI)
cDLL=IniReadPvt("Main","dll","",cINI)
cEmail=IniReadPvt("Main","email","",cINI)
cPwd=IniReadPvt("Main","pwd","",cINI)
nVersion=IniReadPvt("Main","version","",cINI)

ObjectClrOption('appbase', cDLL)
ObjectClrOption('useany', 'Microsoft.Exchange.WebServices')
oEws = ObjectClrNew('Microsoft.Exchange.WebServices.Data.ExchangeService')
oVersion = ObjectClrType('Microsoft.Exchange.WebServices.Data.ExchangeVersion', nVersion )

oEws.Credentials = ObjectClrNew('Microsoft.Exchange.WebServices.Data.WebCredentials', cEmail, cPwd)
oEws.AutodiscoverUrl(cEmail)
oMessage = ObjectClrNew('Microsoft.Exchange.WebServices.Data.EmailMessage', oEws)
oMessage.Subject = 'Test Message'
oBody = ObjectClrNew('Microsoft.Exchange.WebServices.Data.MessageBody')
oBody.Text = 'This message is being sent through EWS with WinBatch CLR hosting'
oMessage.Body = oBody

oMessage.ToRecipients.Add('destination@something.com')
oMessage.SendAndSaveCopy()

Exit
 

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #23 on: December 06, 2017, 06:19:50 am »
Thank you for your patience, and for testing and debugging.  I should have taken a little more time to read the class documentation before posting the original hack. 

Hopefully, it helps the OP.   It will definitely find a place in the Tech Database.
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #24 on: December 06, 2017, 10:00:07 am »
Started looking at the example more carefully before creating a Tech Database article and notice that this line:

oVersion = ObjectClrType('Microsoft.Exchange.WebServices.Data.ExchangeVersion', nVersion )

does not do anything.  The only reason to create a typed version number is to pass it to the EWS service object constructor that accepts it but that is not the constructor being use on the line:

oEws = ObjectClrNew('Microsoft.Exchange.WebServices.Data.ExchangeService')

I will remove line begining "oVersion =" for the Tech Database example.
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


stanl

  • Pundit
  • *****
  • Posts: 668
Re: Send email via SMTP example using .net
« Reply #25 on: December 07, 2017, 03:47:02 am »
Started looking at the example more carefully before creating a Tech Database article and notice that this line:

oVersion = ObjectClrType('Microsoft.Exchange.WebServices.Data.ExchangeVersion', nVersion )

does not do anything.  The only reason to create a typed version number is to pass it to the EWS service object constructor that accepts it but that is not the constructor being use on the line:

oEws = ObjectClrNew('Microsoft.Exchange.WebServices.Data.ExchangeService')

I will remove line begining "oVersion =" for the Tech Database example.

I commented out that line and my script ran fine.

td

  • Tech Support
  • *****
  • Posts: 2222
    • WinBatch
Re: Send email via SMTP example using .net
« Reply #26 on: December 07, 2017, 10:21:03 am »
OK, thanks.
"Success is a lousy teacher. It seduces smart people into thinking they can't lose."
  - Bill Gates


Jeff

  • Newbie
  • *
  • Posts: 11
Re: Send email via SMTP example using .net
« Reply #27 on: Today at 08:36:42 am »
Thanks for the in-depth comments, answers and samples. We have an application sitting at client sites that is capable of sending a report email via SMTP or Exchange Web Services. Whoever developed the app, did not add a button to send a test email. Since the app was built on .net my goal was to enhance my existing WB script to send a test email via SMTP or Exchange web services.

Jeff
Jeff