Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sending e-mail via MAPI to Outlook 4

Status
Not open for further replies.

SitesMasstec

Programmer
Sep 26, 2010
526
Brasil
Hi colleagues!

I had been using a Visual FoxPro 9 application (with MAPI commands) which sends e-mails automaticaly to the Outlook Express. Operating system was Windows XP. It is working well for years.

Now, I installed the same Visual FoxPro 9 application in a computer with Windows 7 Ultimate, , and the mail application is Outlook (not Outlook Express), which I configured accordingly, to receive mails from the Visual FoxPro 9 application.

But my Visual FoxPro 9 application presents error when it try to send mails to Outlook:
"Application is trying to access e-mail address information stored in Outlook..."
Even if I allow, the messages do not go to the Outlook outbox to be sent.

Do you have any solution?

Thank you.
SitesMasstec
 
Hi Olaf,

thankx for Your detailed step by step instruction!

That's exactly the way to go to the settings :)

Cause i don't own an english windows, i could only upload a german screen shot.

Best regards, Stefan
 
Thanks, Stefan.

I have a mixed situation. At work I use english licenses for various reasons, at home german. What I can't contribute is Windows 7 specific screenshots and Thunderbird specific options, but SitesMasstec should now be able to find out, whether Thunderbird is the default client or change that.

Bye, Olaf.
 
Thank you very much Stefan and Olaf!

Yes, I had defined Thunderbird as my Default mail program.

Now, I am going to change my code in order to get the specific error, as Olaf strongly suggested.

I had not done this before because the very same program is working fine in 2 machines:
- One PC with Windows XP Professional & Outlook Express;
- One PC with Windows 7 Home Premium & Thunderbird.

Thanks,
SitesMasstec
 
Well, I strongly suggest you at least LOG (not necessarily display) the error, any error. To be able to see it.

So in the same error handling routine you only display "Problem sending e-mails" you also log AERROR and other info you get, especially what line fails with what error.
Are you doing a TRY..CATCH there? then CATCH TO loException. That'll give you an object based on the Exception class, with several properties of interest:
Details, ErrorNo, LineNo, LineContents, Procedure, StackLevel. All these should be saved to some file, DBF or TXT.

Bye, Olaf.
 
Just to muddy the waters. If you are using MSMAPI32.OCX then you are not using MAPI, you are using Simple MAPI. And, starting with Outlook 2007, Simple MAPI is no longer fully supported.
 
Hello Strongm!

Well it works in these:
Windows XP Professional & Outlook Express
Windows 7 Home Premium & Thunderbird

Do you think I have to change SimpleMAPI (indeed, I did not know about this 'Simple' version) to a 'complete' MAPI? If positive, how to find that MAPI and how to install it?

Thank you,
SitesMasstec
 
The OCX is just a way to use it via OLE class support. One of the well known ways for VFP to use MAPI is via its MSMAPI.MAPISESSION class.
A way not using MSMAPI32.OCX is using CDO.MESSAGE, which needs cdosys.dll. I don't even know a way to use MAPI directly.

MAPI is present on any OS. Neither the MSMAPI32.OCX nor CDOSYS.DLL are always there, but MAPI32.DLL

The situation is more omplicated, though, as wanting to support the default mapi client you have to use what it is using, which is either simple or extended MAPI. The HKLM\Software\Clients\Mail::(default) registry value is telling what the default mail client is binding (but for example not on my Win10 system)

There is one way to explicitly use extended mapi I see over at Craig Boyds site: I wonder whether a default mail client implementing simple mapi is also automated via extended mapi.

You only need to support mapi overall, if you want your mail to appear in the users default mail client outbox/sent items. This is an implicit question for you for the third time. Do you really need this feature of sending the mail through the mail client? This is what makes everything so complicated. It's simpler in regard of dependencies of settings and mail clients to send mails without automating them and instead directly use the SMTP or IMAP protocols, eg by using BLAT.DLL or EXE - don't thnik you have to implement the whole protocols, of course you use a tool that does that for you. If the user should have hands on the mails sent, you could save it to your own applications data. Your app then becomes a mail client itself, though not a MAPI compliant mail client, ie your app is not automatable and you don't contribute to the standard sent items folder.

Bye, Olaf.
 
Hello colleagues!

Error is (using SimpleMAPI):

OLE IDispatch exception code 0 from MAPIMessages... (1429)

Thanks,
SitesMasstec
 
Reminder:

MSMAPI32.OCX (SimpleMAPI) works fine in Windows 7 Home Premium & Thunderbird

SitesMasstec
 
And in what line of which code does this error happen?
And what do other elements of the array you get from AERROR tell?

Bye, Olaf.
 
>works fine in Windows 7 Home Premium & Thunderbird

Unsurprisingly, it (should) work fine with any client that supports Simple MAPI (which Outlook Express and Thunderbird do, but Outlook 2007 and later do not - at least not fully. As I recall they only really implement MAPISendMail)
 


Dear collegues:

Thank you all again for your valuable help.

My application can be configured to execute the 2 types of function: SendViaMAPI and MAPISendMail, in order to try the 2 modes.

Note that I removed the line containing the ON ERROR RETURN(.F.) command.


Command line which show error "OLE IDispatch exception code 0 from MAPIMessages... (1429)":
(program uses one or another command, as it is configured)

IF SendViaMAPI(RemetEmail, destinatario(DESTIN), ASSUNTO, TEXTOTOTAL, @aryAttachments)

or

IF MAPISendMail(RemetEmail, destinatario(DESTIN), ASSUNTO, TEXTOTOTAL, @aryAttachments)




****************************************************
FUNCTION SendViaMAPI(tcFrom, tcTo, tcSubject, tcBody, taFiles)
****************************************************
EXTERNAL ARRAY taFiles
***ON ERROR RETURN(.F.) ==== removed to shiw errors ====
* two new lines:
LOCAL loMapiForm AS FORM
DO FORM MAPI2.SCX NOSHOW NAME loMapiForm LINKED
* your code, slightly modified:
LOCAL loSession, loMessages
*!* loSession = CREATEOBJECT( "MSMAPI.MAPISession" ) && replaced by the next line:
loSession = m.loMapiForm.oleControl1 && control name to be modified by you depending on OLE name on the dummy form
loSession.Signon()
IF (loSession.SessionID > 0)
*!* loMessages = CREATEOBJECT( "MSMAPI.MAPIMessages" ) && replaced by the next line:
loMessages = m.loMapiForm.oleControl2 && control name to be modified by you, too
loMessages.SessionID = loSession.SessionID
ENDIF
WITH loMessages
.Compose()
.RecipDisplayName = tcTo
.RecipType = 1
.ResolveName()
.MsgSubject = tcSubject
.MsgNoteText = tcBody
IF PCOUNT() > 4
FOR lnCountAttachments = 1 TO ALEN(taFiles)
.AttachmentIndex = .AttachmentCount
.AttachmentName = JUSTFNAME(taFiles(lnCountAttachments))
.AttachmentPosition = .AttachmentIndex
.AttachmentPathName = taFiles(lnCountAttachments)
ENDFOR
ENDIF
.SEND(.F.) && T abre o Outlook para enviar, F envia automativamente
* (send in .T. to not send email automatically but instead see it in outlook)
ENDWITH
loSession.Signoff()
STORE .NULL. TO loSession, loMessages
RELEASE loSession, loMessages
RETURN .T.
ENDFUNC





****************************************************
FUNCTION MAPISendMail(tcFrom, tcTo, tcSubject, tcBody, taFiles)
****************************************************
EXTERNAL ARRAY taFiles
***ON ERROR RETURN(.F.) ==== removed to shiw errors ====
* two new lines:
LOCAL loMapiForm AS FORM
DO FORM MAPI2.SCX NOSHOW NAME loMapiForm LINKED
* your code, slightly modified:
LOCAL loSession, loMessages
*!* loSession = CREATEOBJECT( "MSMAPI.MAPISession" ) && replaced by the next line:
loSession = m.loMapiForm.oleControl1 && control name to be modified by you depending on OLE name on the dummy form
loSession.Signon()
IF (loSession.SessionID > 0)
*!* loMessages = CREATEOBJECT( "MSMAPI.MAPIMessages" ) && replaced by the next line:
loMessages = m.loMapiForm.oleControl2 && control name to be modified by you, too
loMessages.SessionID = loSession.SessionID
ENDIF
WITH loMessages
.Compose()
.RecipDisplayName = tcTo
.RecipType = 1
.ResolveName()
.MsgSubject = tcSubject
.MsgNoteText = tcBody
IF PCOUNT() > 4
FOR lnCountAttachments = 1 TO ALEN(taFiles)
.AttachmentIndex = .AttachmentCount
.AttachmentName = JUSTFNAME(taFiles(lnCountAttachments))
.AttachmentPosition = .AttachmentIndex
.AttachmentPathName = taFiles(lnCountAttachments)
ENDFOR
ENDIF
.SEND(.F.) && T abre o Outlook para enviar, F envia automativamente
* (send in .T. to not send email automatically but instead see it in outlook)
ENDWITH
loSession.Signoff()
STORE .NULL. TO loSession, loMessages
RELEASE loSession, loMessages
RETURN .T.
ENDFUNC
 
We're one step further, fine.

You still don't tell the line of error, which line errors.

You can find this out with general error handling via [tt]ON ERROR DO errhandler WITH Lineno()[/tt] - besides other parameters.

See the ON ERROR help topic. Even that simple errHandler routein there is giving more info on any error to you. You don't need to guess which line errors, you can know by LINENO()...


Also see and
If you begin using such standards, you begin to know and not guess or assume, which code fails and why.

Normally I would just take your code, execute and see where it errors, but in this case, it strongly depends on your environment, your computer. So you need to first implement a good error handling routine to know the line of error. Also look into the help topic AERROR. You can use this function also within the errHandler procedure to get more error info. For example the OLE class might have a detail message of importance.

Bye, Olaf.
 
Hello Olaf!

Here are the error message and bellow the code (note that line 395 is .ResolveName() )

Well, strange is that, as I press <enter> in the error message red window, my e-mail was sent to Outbox and from there to the recipients!

Thanks,
SitesMasstec

ErroMensagem_fpk44j.jpg


****************************************************
FUNCTION SendViaMAPI(tcFrom, tcTo, tcSubject, tcBody, taFiles)
****************************************************
EXTERNAL ARRAY taFiles
***ON ERROR RETURN(.F.) retirado nesta versao de teste (EMAITEST.PRG) em 30/03/2016
* two new lines:
LOCAL loMapiForm AS FORM
DO FORM MAPI2.SCX NOSHOW NAME loMapiForm LINKED
* your code, slightly modified:
LOCAL loSession, loMessages
*!* loSession = CREATEOBJECT( "MSMAPI.MAPISession" ) && replaced by the next line:
loSession = m.loMapiForm.oleControl1 && control name to be modified by you depending on OLE name on the dummy form
loSession.Signon()
IF (loSession.SessionID > 0)
*!* loMessages = CREATEOBJECT( "MSMAPI.MAPIMessages" ) && replaced by the next line:
loMessages = m.loMapiForm.oleControl2 && control name to be modified by you, too
loMessages.SessionID = loSession.SessionID
ENDIF
WITH loMessages
.Compose()
.RecipDisplayName = tcTo
.RecipType = 1
.ResolveName() [highlight #FCE94F] <==== LINE 395[/highlight]
.MsgSubject = tcSubject
.MsgNoteText = tcBody
IF PCOUNT() > 4
FOR lnCountAttachments = 1 TO ALEN(taFiles)
.AttachmentIndex = .AttachmentCount
.AttachmentName = JUSTFNAME(taFiles(lnCountAttachments))
.AttachmentPosition = .AttachmentIndex
.AttachmentPathName = taFiles(lnCountAttachments)
ENDFOR
ENDIF
.SEND(.F.) && T abre o Outlook para enviar, F envia automativamente
* (send in .T. to not send email automatically but instead see it in outlook)
ENDWITH
loSession.Signoff()
STORE .NULL. TO loSession, loMessages
RELEASE loSession, loMessages
RETURN .T.
ENDFUNC
 
Now we get warmer. What is the value of tcTo and is this address part of the Thunderbird Address book of that computer?
Are you even needing to resolve tcTo? This method only is needed, if you try to resolve names (First Last) to mailadresses, you can simply skip that step, if tcTo is a mail address, instead simply set .RecipAddress = tcTo

Bye, Olaf.
 
Olaf:

Interestingly, I just changed error routine you suggested (please see the red error window - "Mensagem de erro")

After I pressed <enter> ("Tecle <enter> ") ro close this error window, the e-mail is sent to the Outbox of the Thunderbird e-mail program.

I have not changed anything more in the program except the error routine.

I cannot understand why this happens. I think it should cancel the execution of the program (now, after I press <enter>) as it had done before!

Thanks,
SitesMasstec
 
The error is clearly stating the ResolveName routine has thrown an exception. I don't know what you finally used, as I pointed you to several things, but if the error handling ends by continuing the code and it works, then all you need to remove is - as I already said - the call to the ResolveName maethod.

Besides, did you read, what strongm pointed to? It also confirms, what your error handler tells you: ResolveName does not work. There is a hotfix described there, you coudl do, but you don't need to resolve names to mail adresses, you can simply skip that step, remove that line or comment it out.

Bye, Olaf.
 
Things to do in short:

1. Code change:
Code:
...
WITH loMessages
 .Compose()
 .RecipDisplayName = tcTo
 .RecipAddress= tcTo
 .RecipType = 1
* .ResolveName()
 .MsgSubject = tcSubject
 .MsgNoteText = tcBody
...

2. Hotfix of Mapi32.dll:

If (1) doesn't work, use (2) and then add back the .ResolveName

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top