Tuesday, September 11, 2007

MAPISendMail in C# application

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace MAPIConsole
{
/*
[StructLayout(LayoutKind.Sequential)]
public struct MapiRecipDesc
{
public long Reserved;
public long RecipClass;
public string Name;
public string Address;
public long EIDSize;
public object EntryID;
}

[StructLayout(LayoutKind.Sequential)]
public struct MapiMessage
{
public long Reserved;
public string Subject;
public string NoteText;
public string MessageType;
public string DateReceived;
public string ConversationID;
public long Flags;
public object Originator;
public long RecipCount;
public MapiRecipDesc Recips;
public long FileCount;
public object Files;
}
*/


///
/// A MapiFileDesc structure contains information about a file containing a message attachment
/// stored as a temporary file.
///
/// The file can contain a static OLE object, an embedded OLE object, an embedded message,
/// and other types of files.
///

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiFileDesc
{
///
/// Reserved; must be zero.
///

public uint ulReserved = 0;

///
/// Bitmask of attachment flags. Flags are MAPI_OLE and MAPI_OLE_STATIC.
///
/// If neither flag is set, the attachment is treated as a data file.
///

public uint flFlags = 0;

///
/// An integer used to indicate where in the message text to render the attachment.
///
/// Attachments replace the character found at a certain position in the message text.
/// That is, attachments replace the character in the MapiMessage structure field
/// lpszNoteText[nPosition]. A value of – 1 (0xFFFFFFFF) means the attachment position is
/// not indicated; the client application will have to provide a way for the user to
/// access the attachment.
///

public uint nPosition = 0xffffffff;

///
/// Pointer to the fully qualified path of the attached file.
///
/// This path should include the disk drive letter and directory name.
///

public string lpszPathName = string.Empty;

///
/// Pointer to the attachment filename seen by the recipient, which may differ from the filename in
/// the lpszPathName member if temporary files are being used.
///
/// If the lpszFileName member is empty or NULL, the filename from lpszPathName is used.
///

public string lpszFileName = string.Empty;

///
/// Pointer to the attachment file type, which can be represented with a MapiFileTagExt
/// structure.
///
/// A value of NULL indicates an unknown file type or a file type determined by the operating system.
///

public IntPtr lpFileType = IntPtr.Zero;
}

///
/// MapiFileTagExt structure specifies a message attachment's type at its creation
/// and its current form of encoding so that it can be restored to its original type at its destination.
///
/// A MapiFileTagExt structure defines the type of an attached file for purposes such as encoding and
/// decoding the file, choosing the correct application to launch when opening it, or any use that
/// requires full information regarding the file type.
///
/// Client applications can use information in the lpTag and lpEncoding
/// members of this structure to determine what to do with an attachment.
///

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiFileTagExt
{
///
/// Reserved; must be zero.
///

public uint ulReserved = 0;

///
/// The size, in bytes, of the value defined by the lpTag member.
///

public uint cbTag = 0;

///
/// Pointer to an X.400 object identifier indicating the type of the attachment in its original form,
/// for example "Microsoft Excel worksheet".
///

public IntPtr lpTag = IntPtr.Zero;

///
/// The size, in bytes, of the value defined by the lpEncoding member.
///

public uint cbEncoding = 0;

///
/// Pointer to an X.400 object identifier indicating the form in which the attachment is currently
/// encoded, for example MacBinary, UUENCODE, or binary.
///

public IntPtr lpEncoding = IntPtr.Zero;
}

///
/// A MapiMessage structure contains information about a message.
///

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiMessage
{
///
/// Reserved; must be zero.
///

public uint ulReserved = 0;

///
/// Pointer to the text string describing the message subject,
/// typically limited to 256 characters or less.
///
/// If this member is empty or NULL, the user has not entered subject text.
///

public string lpszSubject = string.Empty;

///
/// Pointer to a string containing the message text.
///
/// If this member is empty or NULL, there is no message text.
///

public string lpszNoteText = string.Empty;

///
/// Pointer to a string indicating a non-IPM type of message.
///
/// Client applications can select message types for their non-IPM messages.
///
/// Clients that only support IPM messages can ignore the lpszMessageType member
/// when reading messages and set it to empty or NULL when sending messages.
///

public string lpszMessageType = null;

///
/// Pointer to a string indicating the date when the message was received.
///
/// The format is YYYY/MM/DD HH:MM, using a 24-hour clock.
///

public string lpszDateReceived = DateTime.Now.ToString("yyyy/MM/dd hh:mm");

///
/// Pointer to a string identifying the conversation thread to which the message belongs.
///
/// Some messaging systems can ignore and not return this member.
///

public string lpszConversationID = string.Empty;

///
/// Bitmask of message status flags.
///
/// The flags are MAPI_RECEIPT_REQUESTED , MAPI_SENT,
/// and MAPI_UNREAD.
///

public uint flFlags = 0;

///
/// Pointer to a MapiRecipDesc structure containing information about the
/// sender of the message.
///

public IntPtr lpOriginator = IntPtr.Zero;

///
/// The number of message recipient structures in the array pointed to by the
/// lpRecips member.
///
/// A value of zero indicates no recipients are included.
///

public uint nRecipCount = 0;

///
/// Pointer to an array of MapiRecipDesc structures, each containing
/// information about a message recipient.
///

public IntPtr lpRecips = IntPtr.Zero;

///
/// The number of structures describing file attachments in the array pointed to by the
/// lpFiles member.
///
/// A value of zero indicates no file attachments are included.
///

public uint nFileCount = 0;

///
/// Pointer to an array of MapiFileDesc structures, each containing
/// information about a file attachment.
///

public IntPtr lpFiles = IntPtr.Zero;
}

///
/// A MapiRecipDesc structure contains information about a message sender or recipient.
///

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
///
/// Reserved; must be zero.
///

public uint ulReserved= 0;

///
/// Contains a numeric value that indicates the type of recipient.
///
/// Possible values are:
///
/// Value Constant Meaning
///
/// 0 MAPI_ORIG Indicates the original sender of the message.
/// 1 MAPI_TO Indicates a primary message recipient.
/// 2 MAPI_CC Indicates a recipient of a message copy.
/// 3 MAPI_BCC Indicates a recipient of a blind copy.
///
///

public uint ulRecipClass= MAPI.MAPI_TO;

///
/// Pointer to the display name of the message recipient or sender.
///

public string lpszName = string.Empty;

///
/// Optional pointer to the recipient or sender's address; this address is provider-specific message
/// delivery data. Generally, the messaging system provides such addresses for inbound messages.
///
/// For outbound messages, the lpszAddress member can point to an address entered by the user for
/// a recipient not in an address book (that is, a custom recipient).
///
/// The format of an address pointed to by the lpszAddress member is [address type][e-mail address].
/// Examples of valid addresses are FAX:206-555-1212 and SMTP:M@X.COM.
///

public string lpszAddress = string.Empty;

///
/// The size, in bytes, of the entry identifier pointed to by the lpEntryID member.
///

public uint ulEIDSize = 0;

///
/// Pointer to an opaque entry identifier used by a messaging system service provider to identify the
/// message recipient. Entry identifiers have meaning only for the service provider;
/// client applications will not be able to decipher them. The messaging system uses this member
/// to return valid entry identifiers for all recipients or senders listed in the address book.
///

public IntPtr lpEntryID = IntPtr.Zero;
}



public class MAPI
{

[DllImport("MAPI32.DLL",EntryPoint = "MAPILogon", CharSet = CharSet.Ansi)]
public static extern UInt32 Logon(IntPtr ulUIParam, string lpszProfileName, string lpszPassword,
UInt32 flFlags, UInt32 ulReserved, ref IntPtr lplhSession);



[DllImport("MAPI32.DLL", EntryPoint = "MAPISendMail", CharSet = CharSet.Ansi)]
public static extern UInt32 SendMail(IntPtr lhSession, IntPtr ulUIParam,
MapiMessage lpMessage, UInt32 flFlags, UInt32 ulReserved);


[DllImport("MAPI32.DLL", EntryPoint = "MAPILogoff", CharSet = CharSet.Ansi)]
public static extern uint Logoff(IntPtr lhSession, IntPtr ulUIParam, uint flFlags, uint ulReserved);



public const int SUCCESS_SUCCESS = 0;
public const int MAPI_USER_ABORT = 1;
public const int MAPI_E_USER_ABORT = MAPI_USER_ABORT;
public const int MAPI_E_FAILURE = 2;
public const int MAPI_E_LOGIN_FAILURE = 3;
public const int MAPI_E_LOGON_FAILURE = MAPI_E_LOGIN_FAILURE;
public const int MAPI_E_DISK_FULL = 4;
public const int MAPI_E_INSUFFICIENT_MEMORY = 5;
public const int MAPI_E_BLK_TOO_SMALL = 6;
public const int MAPI_E_TOO_MANY_SESSIONS = 8;
public const int MAPI_E_TOO_MANY_FILES = 9;
public const int MAPI_E_TOO_MANY_RECIPIENTS = 10;
public const int MAPI_E_ATTACHMENT_NOT_FOUND = 11;
public const int MAPI_E_ATTACHMENT_OPEN_FAILURE = 12;
public const int MAPI_E_ATTACHMENT_WRITE_FAILURE = 13;
public const int MAPI_E_UNKNOWN_RECIPIENT = 14;
public const int MAPI_E_BAD_RECIPTYPE = 15;
public const int MAPI_E_NO_MESSAGES = 16;
public const int MAPI_E_INVALID_MESSAGE = 17;
public const int MAPI_E_TEXT_TOO_LARGE = 18;
public const int MAPI_E_INVALID_SESSION = 19;
public const int MAPI_E_TYPE_NOT_SUPPORTED = 20;
public const int MAPI_E_AMBIGUOUS_RECIPIENT = 21;
public const int MAPI_E_AMBIG_RECIP = MAPI_E_AMBIGUOUS_RECIPIENT;
public const int MAPI_E_MESSAGE_IN_USE = 22;
public const int MAPI_E_NETWORK_FAILURE = 23;
public const int MAPI_E_INVALID_EDITFIELDS = 24;
public const int MAPI_E_INVALID_RECIPS = 25;
public const int MAPI_E_NOT_SUPPORTED = 26;
public const int MAPI_ORIG = 0;
public const int MAPI_TO = 1;
public const int MAPI_CC = 2;
public const int MAPI_BCC = 3;
//***********************
// FLAG Declarations
//***********************
//* MAPILogon() flags *
public const int MAPI_LOGON_UI = 0x1;
public const int MAPI_NEW_SESSION = 0x2;
public const int MAPI_FORCE_DOWNLOAD = 0x1000;
//* MAPILogoff() flags *
public const int MAPI_LOGOFF_SHARED = 0x1;
public const int MAPI_LOGOFF_UI = 0x2;
//* MAPISendMail() flags *
public const int MAPI_DIALOG = 0x8;
//* MAPIFindNext() flags *
public const int MAPI_UNREAD_ONLY = 0x20;
public const int MAPI_GUARANTEE_FIFO = 0x100;
//* MAPIReadMail() flags *
public const int MAPI_ENVELOPE_ONLY = 0x40;
public const int MAPI_PEEK = 0x80;
public const int MAPI_BODY_AS_FILE = 0x200;
public const int MAPI_SUPPRESS_ATTACH = 0x800;
//* MAPIDetails() flags *
public const int MAPI_AB_NOMODIFY = 0x400;
//* Attachment flags *
public const int MAPI_OLE = 0x1;
public const int MAPI_OLE_STATIC = 0x2;
//* MapiMessage flags *
public const int MAPI_UNREAD = 0x1;
public const int MAPI_RECEIPT_REQUESTED = 0x2;
public const int MAPI_SENT = 0x4;

}


class Program
{
/*
public void SendMail()
{
uint ulResult = 0;
IntPtr hSession = IntPtr.Zero;
uint ulFlags = MAPI.MAPI_LOGON_UI | MAPI.MAPI_NEW_SESSION;

ulResult = MAPI.Logon(IntPtr.Zero, null, null, ulFlags, 0, ref hSession);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine(" MAPILogon() fn failed...");
return;
}



MapiRecipDesc recipient = new MapiRecipDesc();
recipient.Reserved = 0;
recipient.RecipClass = MAPI.MAPI_TO;
recipient.Name = null;
recipient.Address = "sundararajan_svks@yahoo.com";
recipient.EIDSize = 0;
recipient.EntryID = null;

MapiMessage message = new MapiMessage();
message.Reserved = 0;
message.Subject = "Greetings From C#";
message.NoteText = "Hello Mr...Sundara rajan";
message.MessageType = null;
message.DateReceived = null;
message.ConversationID = null;
message.Flags = 0;
message.Originator = null;
message.RecipCount = 1;
message.Recips = recipient;
message.FileCount = 0;
message.Files = null;


ulResult = MAPI.SendMail(hSession, IntPtr.Zero, ref message, MAPI.MAPI_NEW_SESSION, 0);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine("SendMail() fn failed...");
return;
}

ulResult = MAPI.Logoff(hSession, IntPtr.Zero, 0, 0);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine("Logoff() fn failed...");
return;
}
}
*/

public void SendMail2()
{
uint ulResult = 0;
IntPtr hSession = IntPtr.Zero;
uint ulFlags = MAPI.MAPI_LOGON_UI | MAPI.MAPI_NEW_SESSION;

ulResult = MAPI.Logon(IntPtr.Zero, null, null, 0, 0, ref hSession);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine(" MAPILogon() fn failed...");
return;
}

MapiMessage message = new MapiMessage();
message.lpszSubject = "Greetings From C#";
message.lpszNoteText = "Hello Mr...Sundara rajan";
message.lpOriginator = IntPtr.Zero;//AllocOrigin();
message.nRecipCount = 1;
message.lpRecips = AllocRecips();

ulResult = MAPI.SendMail(hSession, IntPtr.Zero, message,0, 0);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine("SendMail() fn failed...");
return;
}

ulResult = MAPI.Logoff(hSession, IntPtr.Zero, 0, 0);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine("Logoff() fn failed...");
return;
}

Marshal.FreeHGlobal(message.lpRecips);
}

private IntPtr AllocOrigin()
{
MapiRecipDesc recipient = new MapiRecipDesc();
recipient.ulRecipClass = MAPI.MAPI_ORIG;
recipient.lpszName = "sundar";
recipient.lpszAddress = "sundararajan.svks@gmail.com";
recipient.ulEIDSize = 0;
recipient.lpEntryID = IntPtr.Zero;

Type rtype = typeof(MapiRecipDesc);
int rsize = Marshal.SizeOf(rtype);
IntPtr ptrr = Marshal.AllocHGlobal(rsize);

Marshal.StructureToPtr(recipient, ptrr, false);
return ptrr;

}
private IntPtr AllocRecips()
{
MapiRecipDesc recipient = new MapiRecipDesc();
recipient.ulRecipClass = MAPI.MAPI_TO;
recipient.lpszName = "sundararajan";
recipient.lpszAddress = "sundararajan_svks@yahoo.com";
recipient.ulEIDSize = 0;
recipient.lpEntryID = IntPtr.Zero;

Type rtype = typeof(MapiRecipDesc);
int rsize = Marshal.SizeOf(rtype);
IntPtr ptrr = Marshal.AllocHGlobal(rsize);
Marshal.StructureToPtr(recipient, ptrr, false);
//Marshal.PtrToStructure(
return ptrr;


}
static void Main(string[] args)
{

Program p = new Program();
//p.SendMail();
p.SendMail2();
Console.ReadKey();
}
}
}

2 comments:

Unknown said...
This comment has been removed by the author.
Unknown said...

MAPISendMail is NOT supported under C#. Read: http://blogs.msdn.com/mstehle/archive/2007/10/03/fyi-why-are-mapi-and-cdo-1-21-not-supported-in-managed-net-code.aspx