What seems to be happening is that sometimes the MAPISendMail call never
returns. This usually seems to happen when the program is run, some emails
are sent, the program exits, the program restarts, and some more emails are
sent. What has been noticed is that MAPISP32.EXE remains running between
executions. When the system gets into the state where MAPISendMail hangs, I
have to EndProcess MAPISP32.EXE to get anything mail related to work.
I am running NT 4.0 (sp 3, I think...). Sample code follows....
Jonathan S. Olson
jol...@pcinnovators.com
bool CMapiSupport::bInitializeMapi(void)
{
if ( m_hMapi == NULL )
{
// Load the simple MAPI library.
m_hMapi = LoadLibrary(_T("MAPI32.DLL"));
if ( m_hMapi != NULL )
{
m_lpLogon = (LPMAPILOGON)GetProcAddress(m_hMapi,
_T("MAPILogon"));
m_lpLogoff = (LPMAPILOGOFF)GetProcAddress(m_hMapi,
_T("MAPILogoff"));
m_lpSendMail = (LPMAPISENDMAIL)GetProcAddress(m_hMapi,
_T("MAPISendMail"));
}
if ( (m_lpLogon == NULL) || (m_lpLogoff == NULL) || (m_lpSendMail ==
NULL) )
{
vShutdownMapi();
}
}
return ( m_hMapi != NULL );
}
...
m_hMapiSession = NULL;
if ( (bInitializeMapi()) && (m_lpLogon != NULL) )
{
// Get the MAPI function pointers.
ULONG ulStatus = (*m_lpLogon)(0, bstrProfileName, bstrPassword,
MAPI_NEW_SESSION, 0, &m_hMapiSession);
if ( ulStatus != SUCCESS_SUCCESS )
{
vLogMapiError(pcDestination, ulStatus);
return false;
}
else
{
// Setup the email message
...
ulStatus = (*m_lpSendMail)(m_hMapiSession, 0, &m_structMessage,
0, 0);
}
}
...
void CMapiSupport::vShutdownMapi(void)
{
if ( m_hMapi != NULL )
{
::FreeLibrary(m_hMapi);
m_hMapi = NULL;
}
m_lpLogon = NULL;
m_lpLogoff = NULL;
m_lpSendMail = NULL;
}
It appears that the problem is related to the fact that my program is doing
the following:
MAPILogon
MAPISendMail
MAPILogoff
< Repeat a bunch of times >
It appears that MAPISendMail just queues the message up for delivery, but
doesn't actually deliver the message. After the last MAPILogoff, whatever
messages didn't get actually delivered stay in the queue until some other
MAPI client runs that can deliver them. BUT, MAPISP32.EXE needs to be
killed first, or that MAPI client (Outlook 97 in my case) won't be able to
do any sending or receiving.
I have tested this a number of time in a number of variations, and it seems
that, as long as my program does not call MAPILogoff, all of the messages
will get delivered. So, is there some way to determine if all of the email
has actually been sent? Or am I doing something else wrong?
Thanks!
Jonathan S. Olson
jol...@pcinnovators.com
Jonathan Olson wrote in message ...
>I am using Simple MAPI to send email in a file distribution application.
>It's a relatively simple piece of software that consists of two threads
>(client/GUI thread and the processing thread). The processing thread loads
>the MAPI dll when it is first needed, gettting the MAPILogon, MAPISendMail,
>and MAPILogoff addresses as well. MAPILogon is called to get a session id.
>MAPISendMail is called to actually send the email. And MAPILogoff is
called
>to terminate the session. The dll stays loaded until shutdown, in case
>another email will be sent. Simple, right?
>
>What seems to be happening is that sometimes the MAPISendMail call never
>returns. This usually seems to happen when the program is run, some emails
>are sent, the program exits, the program restarts, and some more emails are
>sent. What has been noticed is that MAPISP32.EXE remains running between
>executions. When the system gets into the state where MAPISendMail hangs,
I
>have to EndProcess MAPISP32.EXE to get anything mail related to work.
>
>I am running NT 4.0 (sp 3, I think...). Sample code follows....
>
< snip >
There are many articles on MSDN regarding problems with the MAPI
spooler. Here is one:
http://support.microsoft.com/support/kb/articles/q179/4/62.asp?FR=0
Personally, I would use SMTP for what you are doing. It is typically
much more reliable.
--
- Eric June ej...@intuitive-data.com
Some additional info on Eric June's reply.
MAPILogon() with MAPI_FORCE_DOWNLOAD flag set does not always force all
messages to be delivered. Depends on how fast your app finishes after the
last send and how fast the MAPISP32 gets the external connection, etc.
MAPILogoff() usually does not return until all messages are delivered if
MAPI_FORCE_DOWNLOAD flag is set with MAPILogon, but I've seen impatient
Win32/Console apps that finish before even the external connection was
established.
You may gain some control over the actual sending of outbound mail by the
FlushQueues() method of Extended MAPI.
By the ScMAPIXFromSMAPI function you can get back a pointer to a MAPI
session object from the Simple MAPI session handle.
From there you can follow the MSDN MAPI SDK sample ROUTE.CLI.
(See function DeliverNow() in source file "Client.c": just as a skeleton;
you'd better cleanup the dirty load-of-goto's-and-Asserts() in MS sample
stuff like this).
On the other hand: is it possible to change the loop:
- while (!Ready) { Logon(); Send(); Logoff() }
into something like:
- Logon(); while (!Ready) { Send(); } Logoff()
As for using SMTP: (if I get Eric right: without using the Personal Folders
bit).
If you use Simple MAPI or CMC with mail clients like Exchange or Outlook you
benefit of the built-in recovery mechanism of the mail client itself.
Unsent messages stay queued until sent once submitted through MAPI/CMC.
Still I only wish (Extended) MAPI would provide for some method to get the
status of the outbound queue.
There is some circumstantial evidence using flags from status table.
But that is tricky stuff I guess.
Anybody have any suggestions/articles on:
***
HOW TO GET STATUS INFO ABOUT UNSENT MESSAGES.
(please)
***
Jacob de Bruin.
Eric June heeft geschreven in bericht
<0999111414114...@intuitive-data.com>...
You said that if FORCE_DOWNLOAD is set during Logon that the spooler will
wait for the Outbox to clear before exiting. The only place that I found
that even mentioned what the spooler does when it exits was an obscure KB
article. It said that, after a connection closes the spooler will exit,
clearing the Outbox first. That's the behavior I'd like, but it appears to
hang instead. I haven't tried using the FORCE_DOWNLOAD, as I'd rather not
have the Logon actually download the messages (this program should be send
only).
As to using Extended MAPI, I was hoping to avoid that. Can't even seem to
find the proper headers and libraries for it.... And having the program
wait while the spooler does its job is a bit annoying. Why can't it
properly send the messages asynchronously in its separate process space
after I Logoff????
Thanks for the response!
Jonathan S. Olson
jol...@pcinnovators.com
Jacob de Bruin wrote in message <838e0e$7d9$1...@news1.xs4all.nl>...
You might want to consider using SMTP (internet mail) and avoiding MAPI
altogether since you are encountering instability problems with the MAPI
spooler. You can use our IDSMail component with code like this:
Dim idsMail as Object
Set idsMail = CreateObject("IDSMailInterface32.Server")
idsMail.ObjectKey = "ABC123"
idsMail.MailSystem =IDSM_SYS_SMTP_POP
idsMail.SMTPServer = "myprovider.com"
idsMail.NewMessage
idsMail.From = "MyName <m...@mycompany.com>"
idsMail.AddRecipientTo "Jim Smith <jsm...@example.com>"
idsMail.AddRecipientCc "Mary Brown <ma...@example.gov>"
idsMail.Subject = "Meeting Agenda"
idsMail.Message = "Here is the agenda for the weekly meeting."
idsMail.AddAttachment "C:\MEETINGS\AGENDA.DOC"
idsMail.Send
The message will be sent to the SMTP server immediately. If you need to
establish a dial-up connection first, you can use the IDSMail Dialer
object. IDSMail also interfaces to any mail systems based on MAPI,
SMTP/POP3 (Internet mail), VIM (Lotus), MHS (Novell), CDO, Active
Messaging, Lotus Notes API, and Banyan VINES. For more info, go to
http://www.intuitive-data.com