Our PB code in 2017 R3 was migrated to windows 10 environment. mail functionality which was working on Win7 no longer works on Outlook 365 (Outlook for Office 365 MSO (16.0.10730.20155)).
We get Microsoft Outlook Error
"Either there is no default mail client or the current mail client cannoy fulfill the messaging request. Please run Microsoft Outlook and run it as default."
"Login Failed"
Our code looks like this;
// Create a mail session
mSes = create mailSession
// Log on to the session
mRet = mSes.mailLogon("Default","")
IF mRet <> mailReturnSuccess! THEN
mRet = mSes.mailLogon(mailNewSession!)
IF mRet <> mailReturnSuccess! THEN
MessageBox("Mail", 'Logon failed.')
RETURN
END IF
END IF
Things tried:
Outlook is open all the time
I tried setting Outlook as default through settings,
Added [PB]
UseSimpleMAPI=yes
to pb.ini, but no luck.
As previously mentioned in this thread, here is documentation about the HTTPClient object of PB 2017 R3, which you would use to make the REST Web API calls: https://www.appeon.com/support/documents/appeon_online_help/pb2017r3/objects_and_controls/ch02s37.html
SMTP
=====
It all depends on what you need to do in Outlook. If you just want to send emails, then I suggest looking at sending emails via SMTP, examples can be found all over the net by searching for 'PowerBuilder SMTP'.
C# COM Component
================
If you want emails to be in the user's Sent Items in Outlook, and you want to look at address books and calendar items then you need probably need to integrate with Outlook.
My suggestion for this is to create a .NET COM callable dll that does all the work for you. It is a pain to get up and working the first time but once you have, then you have access to all the .NET examples and tutorials out there, and you are learning a new useful skill.
Here are some details on how to do this:
https://stackoverflow.com/questions/842017/net-interop-in-powerbuilder?rq=1
https://tomkrueger.wordpress.com/2010/02/22/calling-net-from-powerbuilder/
My .NET library for my company, handles integration with Outlook, SMTP, PDF, SharePoint, Word, Excel and many other things that are so easy to do once you have a little bit of C# and a working dll.
EWS
====
I personally have not used the Exchange Web Services API, but a quicj search in Google brings up some hints on how to use it with PowerBuilder
https://answers.sap.com/questions/10813877/exchange-web-services-api-how-to-connectaccess-usi.html
Third-party Active/X
===============
If you'd like it to be really simple but not free, then checkout something like the Chilkat libraries
https://www.example-code.com/powerbuilder/outlook.asp
I followed the same approach to send mail and to make updates in the Outlook calendar.
For sure it is not ideal (a window command command opens to run the script and it's ugly) but at least it works... Maybe would it be better to implement the functionalities in a C dll and call it from PB but I don't know how to.
Powershell example. Note that there are some differences between on premise and online mailboxes.
param(
[Parameter(Mandatory=$false)]
[String]$from=$(throw "Sending email adress must be given with -from"),
[Parameter(Mandatory=$false)]
[String]$filename=$(throw "csv filename to import must be given with -filename"),
[Parameter(Mandatory=$false)]
[string]$path,
[Parameter(Mandatory=$false)]
[string]$pwd
)
# load EWS module
if($path -eq "") {
$path = "."
}
Add-Type -Path $path"\Microsoft.Exchange.WebServices.dll"
# Create a Service Object and set Exchange 2010_SP2 version. If you don't set it, the default one is Exchange 2013.
$version = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($version)
# Specify EWS URL, if you do not want to (or cannot) use autodiscover.
# Exchange on premise: Autodiscover OR https://.../Exchange.asmx
# Exchange online : doesn't support autodiscover, use url https://.../Exchange.asmx
# Check with autodiscover. If it throws an exception, use EWS online url.
try {
$service.AutodiscoverUrl($from)
$srvType = "OP"
}
Catch {
$service.url = "https://.../Exchange.asmx"
$srvType = "OL"
$Error.Clear()
}
# Set credentials
# Exchange on premise : can use Windows default credentials
# Exchange online : must use explicit credentials property, pwd must have been given as argument. Better : use OAUTH authentication !
if ($srvType -eq "OP") {
$service.UseDefaultCredentials = $true
} else {
if($pwd -eq "") {
throw "Exchange ONLINE : password must be given"
}
$service.Credentials = new-object Microsoft.Exchange.WebServices.Data.WebCredentials($from, $pwd)
}
# Sending emails
# Import data from .csv file
$mailItems = Import-CSV $filename
foreach($item in $mailItems){
# Create the message Object
$message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service
$message.From = $from
# Set the Subject and Body
$message.Subject = $item.subject
# Body type is HTML by default. Declare body type is TEXT to retain linefeed and so on.
$message.Body = new-object Microsoft.Exchange.WebServices.Data.MessageBody([Microsoft.Exchange.WebServices.Data.BodyType]::Text,$item.body)
# Set recipient list. Several recipients can be set in $To (comma separated).
$item.to.Split(",") | ForEach-Object {
$null = $message.ToRecipients.Add($_)
}
# Add attachment(s), if any. Several attachments can be set in $Attach (comma separated).
if ($item.attach){
$item.attach.Split(",") | ForEach-Object {
if (Test-Path $_) {
$message.Attachments.AddFileAttachment("$_")
}
}
}
try {
$message.SendAndSaveCopy()
}
catch {
write-Host "Error !"
throw $error
}
}