Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / ATL
Article

Sending Email using MAPI - A COM DLL

Rate me:
Please Sign up or sign in to vote.
4.86/5 (18 votes)
29 May 20035 min read 343.8K   8.3K   68   70
How to automatically send customized emails messages and attachments?

Sample Image - TestEmail.jpg

Introduction

During the software development, I have seen many applications that requires incorporating email support. I remember, once I was to develop an application, which sends emails at the specific time to specific people with the customized messages. For that I developed a COM service that used MAPI. MAPI, i.e. Messaging Application Programming Interface, is the standard messaging architecture and a complete set of functions and object-oriented interfaces. Here I have an Email component, a COM DLL, which is a set of messaging functions that helps you create messaging-enabled applications. This COM component uses Simple MAPI to achieve that.

Note: MAPI is used by various industry-standard e-mail clients, such as the Microsoft Exchange client, all versions of Microsoft Outlook and Outlook Express, including QUALCOMM Incorporated (Eudora) and Netscape Communications Corporation. So you can use this component with these client applications also.

Component Design

The CLSID of the Email component is CLSID_Mail and it has only one interface IMail with the interface ID IID_IMail.

CMail is the implementation class and contains following data members:

m_MAPILogonFunction pointer for MAPILogon
m_MAPISendMail Function pointer for MAPISendMail
m_MAPISendDocumentsFunction pointer for MAPISendDocuments
m_MAPIFindNext Function pointer for MAPIFindNext
m_MAPIReadMail Function pointer for MAPIReadMail
m_MAPIResolveNameFunction pointer for MAPIResolveName
m_MAPIAddress Function pointer for MAPIAddress
m_MAPILogoff Function pointer for MAPILogoff
m_MAPIFreeBufferFunction pointer for MAPIFreeBuffer
m_MAPIDetails Function pointer for MAPIDetails
m_MAPISaveMail Function pointer for MAPISaveMail

IMail have the following functions:

IsMapiInstalled Checks if the MAPI is installed on the system. It searches Win.INI file for the MAPI key. If found it returns S_OK.
InitMapi After checking the through IsMapiInstalled, it initializes the MAPI function pointers. Method should be called once before using the component.
put_strProfileName Takes the name of the outlook profile name you are using to send the email.
put_strEmailAddressSets the recipient email address. You can specify more than one comma (,) separated recipient addresses.
put_strRecipientSets the name you want to specify for the recipients, sets the email names of the sender – it may be different from your specified profile email address.
put_strSubjectSets the subject of the email.
get_strSubjectReturns the email subject.
put_strMessageSets email message text.
get_strMessageReturns message text.
put_strAttachmentFilePathSets the email attachment with the full path like “c:\abc.txt”.
get_strAttachmentFilePathReturns the path of email attachment.
put_strAttachmentFileThe display name of the attachment (Sample.txt), by default, it’s the same as that specified in put_strAttachmentFilePath.
get_strAttachmentFileReturns the attachment file name.
LogonOpens a new logon session if not already opened, using specified outlook profile, name and the profile password, you must logon before sending the email. I have set password to NULL assuming that the profile you will specify have NO password, but you can specify your own password. Automatically called by Send method.
LogoffLogs off, and closes the session. Automatically called by Send method after sending the email.
SendSends the email, requires valid outlook profile name, recipient email address and a login session to send email.

Steps to execute the demo project

The demo project demonstrates the way you can use the component to send an email. In order to execute the demo project, the following settings are required:

Step 1: You must have some valid Output Express email account or create one named TestProfile.

You can create an email profile in Express from Tools>Accounts menu. This will open Internet Accounts property sheet. On the tab All, click the button Add and then Mail. A wizard will let you create an email account, specify the valid email address. For hotmail account, wizard automatically sets the names of email servers.

Sample Image- Account

After successfully creating the account, select the account name from the list in All tab (for hotmail account, the default account name is Hotmail). Open account properties by pressing Properties button and change the account name from default name (say Hotmail) to TestProfile.

Sample Image

Step 2: Register the DLL

All COM DLLs required to be registered. After copying the DLL source code, you can register the DLL by right clicking the DLL and selecting Register DLL or Register COM component option, or simply by double clicking the DLL. Compiling the DLL code in Visual Studio will automatically register the DLL.

Step 3: Logged on to the net

Make sure you are logged on to the net. If not, outlook will fail to deliver the email, however, you can still check the composed email in your outbox.

How to send email?

After specifying the information in the dialog box, click the Send button. A warning message will be displayed, click Send button.

Warning

Note:The warning dialog is displayed because of the security constraints. If you want to get rid of this dialog box, then you will have to use Extended MAPI instead of simple MAPI.

Sending

Here is the method CTestEmailDlg::OnSend method, which is used to pass the user specified information to the email object and call the IMail::Send method after setting everything.

//##//##//////////////////////////////////////////////////////////////

///////////////////////////////////////////////
//
//  void CTestEmailDlg::OnSend() 
//
//    This module is called when send button is pressed and uses 
//Email COM DLL to send 

email - Aisha Ikram
// Note: dont forget to initialize COM library using CoInitialize(NULL);
//##//##////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////

void CTestEmailDlg::OnSend() 
{
  UpdateData();
  try{
       
    CComPtr<IMAIL> objMail;
        
    HRESULT hr;
    // make sure the DLL is registered
    hr = objMail.CoCreateInstance(CLSID_Mail);
    if(SUCCEEDED(hr))
    {
      if(hr== S_OK)
      {
        // profile name is compulsory, this is the outlook profile, 
        // i used "outlook express" as configuring it is easier than 
       // "MS outlook" make sure to specify the correct sender's address 
       // for this profile and make sure that outlook express is 
       //the default email client.
    
       if(m_strProfile.IsEmpty())
       {    
         AfxMessageBox("Please specify email profile name ");
         return;    
       }
                
       if(m_strTo.IsEmpty())
       {
         AfxMessageBox("Please specify recipient's email address ");
         return;
       }
       // by default, it's TestProfile, assumes that a profile with this 
       //name exists in outlook
       hr= objMail->put_strProfileName((_bstr_t)m_strProfile);
                
       hr = objMail->put_strSubject((_bstr_t)m_strSubject);
                
       // this is the email or set of email addresses (separated by ,)
       // which is actually used to send email            
       hr = objMail->put_strEmailAddress((_bstr_t)m_strTo);
                
       // recipient is just to show the display name
       hr = objMail->put_strRecipient((_bstr_t)m_strTo);
                
       hr = objMail->put_strAttachmentFilePath((_bstr_t)m_strAttachment);
                
       hr = objMail->put_strMessage((_bstr_t)m_strMessage);

       hr= objMail->Send();

       if(hr!=S_OK)
         AfxMessageBox("Error, make sure the info is correct");
       }//if
     } //if
   } // try
   catch(...)
   {
     AfxMessageBox("Error, make sure specified info is correct");
   }
}

Check the mail in the recipient inbox.

New Msg

Where to use

This component can be extended to incorporate the functionalities like opening an existing inbox to read emails automatically from the inbox and composing new emails etc. It can be used to send emails automatically with customized user messages and attachments to specific people at particular time, especially while using some exe servers or NT services.

That's it. If there is any suggestions or comments you are most welcome. Your rating would help me evaluate the standard of my article.

Looking for a Class instead of a COM component?

I have also build a class CSMAPI, to use simple MAPI to send email, read and find a message and more is to be added. You can find this class, which you can use anywhere (either in win32, or MFC or ATL) and the demo project in MFC.

You can find all at my website (free code and articles website).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect DWP
United Kingdom United Kingdom
I am currently working as Lead Solution Architect for Azure, AWS and hybrid cloud. I have been using and defining reference architecture, blueprint and patterns across digital. working with different vendors like Microsoft, Amazon, Redhat, Palo Alto, Venafi, Atlassian, Oracle and Google.
I have worked as an architect for many other renowned govt and private organziations in UK like NHS, DfE, Liaison, Cloudsprint etc.

I was historically working as a Technical Lead. I worked mainly in microsoft technologies,Windows, .NET, C#, VB.NET, ASP.NET, VC++ 6, MFC, ATL, COM/DCOM, SQL Server.

Comments and Discussions

 
Questionhi Pin
Member 1223355410-Apr-17 22:40
Member 1223355410-Apr-17 22:40 
GeneralWithout user interaction Pin
Zoltan16-Feb-10 7:48
Zoltan16-Feb-10 7:48 
Questionhelp me to eleminate confim message of windows mail by using mapi Pin
praswani@indiatimes.com26-Apr-09 20:52
praswani@indiatimes.com26-Apr-09 20:52 
GeneralVista "Windows Mail" Pin
Member 259584526-May-08 12:29
Member 259584526-May-08 12:29 
GeneralRe: Vista "Windows Mail" Pin
xirc_za4-Oct-08 10:56
xirc_za4-Oct-08 10:56 
GeneralRe: Vista "Windows Mail" Pin
Member 259584517-Dec-08 7:51
Member 259584517-Dec-08 7:51 
GeneralSending Mail on a different Thread in C# with Attachments Pin
Riaz Afridi25-Jul-07 14:31
Riaz Afridi25-Jul-07 14:31 
GeneralThanks Pin
mjkhan78618-Mar-07 4:51
mjkhan78618-Mar-07 4:51 
GeneralSending mail using Simple MAPI Pin
kunal.tawde27-Feb-07 18:13
kunal.tawde27-Feb-07 18:13 
GeneralSending Mail using MAPI doesn't work with MS Outlook. Pin
kunal.tawde26-Feb-07 23:55
kunal.tawde26-Feb-07 23:55 
GeneralSending a Email without user's intervention Pin
venki.v21-Sep-06 1:06
venki.v21-Sep-06 1:06 
Hi I need to send Email from application without user's intervention. I am using VC++ 6.0 and simple MAPI. I should not be getting a dialog while the mail is being sent. Here is my code.
<br />
<br />
#include <mapi.h><br />
#include <iostream.h><br />
#include <stdio.h><br />
<br />
LPMAPILOGON lpfnMAPILogon;<br />
LPMAPISENDMAIL lpfnMAPISendMail;<br />
LPMAPILOGOFF lpfnMAPILogoff;<br />
<br />
MapiRecipDesc lpSendDesc;<br />
MapiRecipDesc recipient;<br />
MapiMessage message;<br />
<br />
<br />
void main(void)<br />
{<br />
<br />
    LHANDLE lhSession;<br />
<br />
    HINSTANCE hMAPILib;<br />
	LPMAPISESSION lpMAPISession = NULL;<br />
<br />
	char lszName[] = "Saipoornima Somanchy";<br />
<br />
    hMAPILib = LoadLibrary("MAPI32.DLL");<br />
<br />
    lpfnMAPILogon = (LPMAPILOGON)GetProcAddress(hMAPILib, "MAPILogon");<br />
    lpfnMAPISendMail = (LPMAPISENDMAIL)GetProcAddress(hMAPILib, "MAPISendMail");<br />
    lpfnMAPILogoff = (LPMAPILOGOFF)GetProcAddress(hMAPILib, "MAPILogoff");<br />
<br />
	// intiallizing the mail recipents -- sender's structure<br />
	lpSendDesc.ulRecipClass = MAPI_ORIG;<br />
	lpSendDesc.lpszName = lszName;<br />
	lpSendDesc.lpszAddress = "SMTP:saipoornima.somanchy@valuelabs.net";<br />
	lpSendDesc.ulEIDSize = 0;<br />
	lpSendDesc.lpEntryID = NULL;<br />
	<br />
	// initiallizing the mali recipents description -- receivers structure;<br />
	recipient.ulRecipClass = MAPI_TO;<br />
	recipient.lpszName = "SSP";<br />
	recipient.lpszAddress = "SMTP:saipoornima.somanchy@valuelabs.net";<br />
	recipient.ulEIDSize = 0;<br />
	recipient.lpEntryID = NULL;<br />
	<br />
<br />
	// initiallizing the message structure.<br />
	message.ulReserved = 0;<br />
	message.lpszSubject = "Test";<br />
	message.lpszNoteText = "This is a test message";<br />
	message.lpszMessageType = NULL;<br />
	message.lpszDateReceived = NULL;<br />
	message.lpszConversationID = NULL;<br />
	message.flFlags = 0L;<br />
	message.lpOriginator = &lpSendDesc;<br />
	message.nRecipCount = 1;<br />
	message.lpRecips = &recipient;<br />
	message.nFileCount = 0;<br />
	message.lpFiles = NULL;<br />
	<br />
<br />
     ULONG lunFuntRetVal = lpfnMAPILogon(0, NULL, NULL, MAPI_LOGON_UI, 0,&lhSession);<br />
     ULONG lunFuntRetVal1 = lpfnMAPISendMail(0,0,&message,0,0);<br />
     ULONG lunFuntRetVal2 = lpfnMAPILogoff(lhSession,0,0,0);<br />
	<br />
	 if (lunFuntRetVal1 == SUCCESS_SUCCESS)<br />
	 {<br />
		 printf("Message sent.\n");<br />
	 }<br />
	 else<br />
		 printf("Failed Sending message\n");<br />
	<br />
	 cout<<"Error Code:"<<lunFuntRetVal1<<endl;<br />
    <br />
<br />
    FreeLibrary(hMAPILib);<br />
<br />
}<br />


If I use this statement
ULONG lunFuntRetVal1 = lpfnMAPISendMail(0,0,&message,0,0);
I am getting a unspecified error. Error number 26.

If I use this statement
ULONG lunFuntRetVal1 = lpfnMAPISendMail(0,0,&message,MAPI_LOGON_UI,0);
I am getting a warning dialog saying that an application is trying to send you a mail....
which I shud not get

How do I correct this to send the mail automatically to the address specifed when I run this application.

Thanks in Advance
GeneralSample heading Pin
Shahid_2k_whiz13-Jul-06 23:52
Shahid_2k_whiz13-Jul-06 23:52 
Generalnice job Pin
ivan françois29-Mar-06 21:59
ivan françois29-Mar-06 21:59 
GeneralRe: nice job Pin
Aisha Ikram2-Apr-06 23:48
Aisha Ikram2-Apr-06 23:48 
GeneralThank you Pin
Pablo Aliskevicius6-Mar-06 20:12
Pablo Aliskevicius6-Mar-06 20:12 
QuestionRegarding folders of all the identities in outlook express Pin
rajeevktripathi22-Nov-05 1:55
rajeevktripathi22-Nov-05 1:55 
Generalinternet status Pin
Kutti Ra30-Sep-05 16:14
Kutti Ra30-Sep-05 16:14 
GeneralMultiple recipients Pin
angeltsoi19-Jul-05 22:26
angeltsoi19-Jul-05 22:26 
GeneralRe: Multiple recipients Pin
Member 180440317-Aug-11 4:39
Member 180440317-Aug-11 4:39 
Generalsignatures are not sent! Pin
schaereran@gmx.net20-Apr-04 23:44
schaereran@gmx.net20-Apr-04 23:44 
Generalit giving me login failure message when i debug Pin
Rajesh match1-Apr-04 23:04
Rajesh match1-Apr-04 23:04 
GeneralMapi ResolveName Fail. Result = -2147467259 Pin
Anonymous10-Mar-04 11:51
Anonymous10-Mar-04 11:51 
GeneralChoosing Profile make no difference Pin
Ripal Vaidya29-Jan-04 18:54
Ripal Vaidya29-Jan-04 18:54 
Generalregistering dll Pin
halwas24-Dec-03 4:24
halwas24-Dec-03 4:24 
GeneralRe: registering dll Pin
halwas24-Dec-03 5:09
halwas24-Dec-03 5:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.