123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Runtime.InteropServices;
- using System.IO;
- namespace FastReport.Export.Email
- {
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
- internal class MapiMessage
- {
- public int reserved;
- public string subject;
- public string noteText;
- public string messageType;
- public string dateReceived;
- public string conversationID;
- public int flags;
- public IntPtr originator;
- public int recipCount;
- public IntPtr recips;
- public int fileCount;
- public IntPtr files;
- }
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
- internal class MapiRecipDesc
- {
- public int reserved;
- public int recipClass;
- public string name;
- public string address;
- public int eIDSize;
- public IntPtr entryID;
- }
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
- internal class MapiFileDesc
- {
- public int reserved;
- public int flags;
- public int position;
- public string pathName;
- public string fileName;
- public IntPtr fileType;
- }
- /// <summary>
- /// Allows to send message using MAPI interface.
- /// </summary>
- public static class MAPI
- {
- #region static
- const int MapiLogonUI = 0x00000001;
- const int MAPI_DIALOG = 0x8;
- const int MAPI_TO = 1;
- const int MAPI_CC = 2;
- [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
- private static extern int MAPISendMail(IntPtr session, IntPtr uiParam,
- MapiMessage message, int flags, int reserved);
- [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
- private static extern int MAPILogon(IntPtr hwnd, string profileName, string password,
- int flags, int reserved, ref IntPtr session);
- [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
- private static extern int MAPILogoff(IntPtr session, IntPtr hwnd,
- int flags, int reserved);
- private static string[] errors = new string[] {
- "OK [0]", "User abort [1]", "General MAPI failure [2]",
- "MAPI login failure [3]", "Disk full [4]",
- "Insufficient memory [5]", "Access denied [6]",
- "-unknown- [7]", "Too many sessions [8]",
- "Too many files were specified [9]",
- "Too many recipients were specified [10]",
- "A specified attachment was not found [11]",
- "Attachment open failure [12]",
- "Attachment write failure [13]", "Unknown recipient [14]",
- "Bad recipient type [15]", "No messages [16]",
- "Invalid message [17]", "Text too large [18]",
- "Invalid session [19]", "Type not supported [20]",
- "A recipient was specified ambiguously [21]",
- "Message in use [22]", "Network failure [23]",
- "Invalid edit fields [24]", "Invalid recipients [25]",
- "Not supported [26]"
- };
- #endregion
- private static MapiMessage CreateMessage(string[] files, string mailSubject, string mailBody,
- string[] recipientName, string[] recipientAddress)
- {
- MapiMessage msg = new MapiMessage();
- msg.subject = mailSubject;
- msg.noteText = mailBody;
- if (files.Length > 0)
- {
- msg.fileCount = files.Length;
- msg.files = GetFilesDesc(files);
- }
- if (recipientAddress.Length > 0)
- {
- msg.recipCount = recipientAddress.Length;
- msg.recips = GetRecipDesc(recipientName, recipientAddress);
- }
- return msg;
- }
- private static IntPtr GetFilesDesc(string[] files)
- {
- IntPtr ptra = AllocMemory(typeof(MapiFileDesc), files.Length);
- for (int i = 0; i < files.Length; i++)
- {
- MapiFileDesc fileDesc = new MapiFileDesc();
- fileDesc.position = -1;
- fileDesc.fileName = Path.GetFileName(files[i]);
- fileDesc.pathName = files[i];
- Marshal.StructureToPtr(fileDesc, OffsetPtr(ptra, typeof(MapiFileDesc), files.Length - 1 - i), false);
- }
- return ptra;
- }
- private static IntPtr GetRecipDesc(string[] recipientName, string[] recipientAddress)
- {
- IntPtr ptra = AllocMemory(typeof(MapiRecipDesc), recipientAddress.Length);
- for (int i = 0; i < recipientAddress.Length; i++)
- {
- MapiRecipDesc recipDesc = new MapiRecipDesc();
- recipDesc.recipClass = i == 0 ? MAPI_TO : MAPI_CC;
- if (recipientName.Length > i)
- recipDesc.name = recipientName[i];
- recipDesc.address = recipientAddress[i];
- Marshal.StructureToPtr(recipDesc, OffsetPtr(ptra, typeof(MapiRecipDesc), recipientAddress.Length - 1 - i), false);
- }
- return ptra;
- }
- private static IntPtr AllocMemory(Type structureType, int count)
- {
- return Marshal.AllocHGlobal(Marshal.SizeOf(structureType) * count);
- }
- private static IntPtr OffsetPtr(IntPtr ptr, Type structureType, int offset)
- {
- return (IntPtr)((long)ptr + offset * Marshal.SizeOf(structureType));
- }
- private static void Logoff(IntPtr hwnd, IntPtr session)
- {
- if (session != IntPtr.Zero)
- {
- MAPILogoff(session, hwnd, 0, 0);
- session = IntPtr.Zero;
- }
- }
- private static bool Logon(IntPtr hwnd, ref IntPtr session)
- {
- int error = MAPILogon(hwnd, null, null, 0, 0, ref session);
- if (error != 0)
- error = MAPILogon(hwnd, null, null, MapiLogonUI, 0, ref session);
- return error == 0;
- }
- private static void DisposeMessage(MapiMessage msg)
- {
- FreeMemory(msg.files, typeof(MapiFileDesc), msg.fileCount);
- FreeMemory(msg.recips, typeof(MapiRecipDesc), msg.recipCount);
- msg = null;
- }
- private static void FreeMemory(IntPtr ptr, Type structureType, int count)
- {
- if (ptr != IntPtr.Zero)
- {
- for (int i = 0; i < count; i++)
- {
- Marshal.DestroyStructure(OffsetPtr(ptr, structureType, i), structureType);
- }
- Marshal.FreeHGlobal(ptr);
- }
- }
- /// <summary>
- /// Sends a message.
- /// </summary>
- /// <param name="handle">Parent window handle.</param>
- /// <param name="files">Files to attach.</param>
- /// <param name="mailSubject">Email subject.</param>
- /// <param name="mailBody">Email body.</param>
- /// <param name="recipentName">Recipient names.</param>
- /// <param name="recipientAddress">Recipient addresses.</param>
- /// <returns>Error code. <b>0</b> if operation was completed succesfully.</returns>
- public static int SendMail(IntPtr handle, string[] files, string mailSubject, string mailBody,
- string[] recipentName, string[] recipientAddress)
- {
- IntPtr session = IntPtr.Zero;
- int error = 0;
- if (Logon(handle, ref session))
- {
- MapiMessage msg = CreateMessage(files, mailSubject, mailBody, recipentName, recipientAddress);
- error = MAPISendMail(session, handle, msg, MAPI_DIALOG, 0);
- Logoff(handle, session);
- DisposeMessage(msg);
- }
- return error;
- }
- /// <summary>
- /// Returns a text describing an error.
- /// </summary>
- /// <param name="error">The error code.</param>
- /// <returns>The text describing an error.</returns>
- public static string GetErrorText(int error)
- {
- if (error <= 26)
- return errors[error];
- return "MAPI error [" + error.ToString() + "]";
- }
- }
- }
|