Click here to Skip to main content
Email Password   helpLost your password?

Screenshot - SendToNET2.jpg

Updates

By popular demand, this article has been updated to provide for multiple attachments and recipients.

Introduction

Not unlike The Terminator, my previous article explaining how to programmatically add attachments to emails was meant to be a low budget offering for a very straightforward but useful addition to your GUIs. I hadn't quite expected the tsunami of emails and comments, particularly questions about how to do all this in C# and VB.NET. Hopefully, this article will answer those questions and be like Terminator 2 - the ultimate sequel.

And like all good sequels, there are problems along the way. It's not actors wanting exorbitant fees that's the issue. For us, it's the pain of calling unmanaged code - MAPI32 - from managed code. We'll need to delve into the world of .NET Interop Marshaling to explain how some of this works. We'll be using PInvoke - a.k.a. Platform Invoke - to make this all work.

The sample code provides both C# and VB.NET versions, with a simple test program for each.

There's a new Marshaler in town

.NET provides a language-independent development system enabling you to write classes in VB, C++, or C#, and use them in other languages; you can even derive from classes in a different language. But how do you call a function in an unmanaged DLL? You have to somehow convert your C# and VB objects into the necessary structs, char*'s, and function pointers the unmanaged DLL expects. In other words, your parameters must be marshaled.

Marshaling is a complex topic (see MSDN), and Microsoft has gone to great lengths to support unmanaged code interop and COM interop, so I guess they think unmanaged code will be around for a while! Fortunately, the parts we need for this example are pretty straightforward. To call a DLL function from C#, you must declare a function that will tell the compiler where the exported entry point is in the unmanaged DLL - in this case MAPI32.DLL. The DLLImport attribute does this for you.

using System.Runtime.InteropServices;

[DllImport("MAPI32.DLL")]
private static extern int MAPISendMail(IntPtr sess, 
        IntPtr hwnd, MapiMessage message, int flg, int rsv);

The interop in .NET provides default marshaling to handle common types for parameters like strings and ints. Unfortunately, many Win32 API calls use pointers to unmanaged structs so you have to manage your own marshaling for these. You need to create a C# class or struct that mirrors the required unmanaged struct, choose the necessary types within the struct, and mark it up with the [StructLayout] attribute. This is necessary because the CLR controls the physical layout of memory, so if the class needs to be arranged in an expected way, use [StructLayout] to preserve the layout, and .NET will not mess with it.

Default marshaling gotchas

The C# way

using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Collections.Generic;
using System.Windows.Forms;

namespace SendFileTo
{
    class MAPI
    {
        public bool AddRecipientTo(string email)
        {
            return AddRecipient(email, HowTo.MAPI_TO);
        }

        public bool AddRecipientCC(string email)
        {
            return AddRecipient(email, HowTo.MAPI_TO);
        }

        public bool AddRecipientBCC(string email)
        {
            return AddRecipient(email, HowTo.MAPI_TO);
        }

        public void AddAttachment(string strAttachmentFileName)
        {
            m_attachments.Add(strAttachmentFileName);
        }

        public int SendMailPopup(string strSubject, string strBody)
        {
            return SendMail(strSubject, strBody, MAPI_LOGON_UI | MAPI_DIALOG);
        }

        public int SendMailDirect(string strSubject, string strBody)
        {
            return SendMail(strSubject, strBody, MAPI_LOGON_UI);
        }


        [DllImport("MAPI32.DLL")]
        static extern int MAPISendMail(IntPtr sess, IntPtr hwnd, 
            MapiMessage message, int flg, int rsv);

        int SendMail(string strSubject, string strBody, int how)
        {
            MapiMessage msg = new MapiMessage();
            msg.subject = strSubject;
            msg.noteText = strBody;

            msg.recips = GetRecipients(out msg.recipCount);
            msg.files = GetAttachments(out msg.fileCount);

            m_lastError = MAPISendMail(new IntPtr(0), new IntPtr(0), msg, how, 
                0);
            if (m_lastError > 1)
                MessageBox.Show("MAPISendMail failed! " + GetLastError(), 
                    "MAPISendMail");

            Cleanup(ref msg);
            return m_lastError;
        }

        bool AddRecipient(string email, HowTo howTo)
        {
            MapiRecipDesc recipient = new MapiRecipDesc();

            recipient.recipClass = (int)howTo;
            recipient.name = email;
            m_recipients.Add(recipient);

            return true;
        }

        IntPtr GetRecipients(out int recipCount)
        {
            recipCount = 0;
            if (m_recipients.Count == 0)
                return IntPtr.Zero;

            int size = Marshal.SizeOf(typeof(MapiRecipDesc));
            IntPtr intPtr = Marshal.AllocHGlobal(m_recipients.Count * size);

            int ptr = (int)intPtr;
            foreach (MapiRecipDesc mapiDesc in m_recipients)
            {
                Marshal.StructureToPtr(mapiDesc, (IntPtr)ptr, false);
                ptr += size;
            }

            recipCount = m_recipients.Count;
            return intPtr;
        }

        IntPtr GetAttachments(out int fileCount)
        {
            fileCount = 0;
            if (m_attachments == null)
                return IntPtr.Zero;

            if ((m_attachments.Count <= 0) || (m_attachments.Count > 
                maxAttachments))
                return IntPtr.Zero;

            int size = Marshal.SizeOf(typeof(MapiFileDesc));
            IntPtr intPtr = Marshal.AllocHGlobal(m_attachments.Count * size);

            MapiFileDesc mapiFileDesc = new MapiFileDesc();
            mapiFileDesc.position = -1;
            int ptr = (int)intPtr;
            
            foreach (string strAttachment in m_attachments)
            {
                mapiFileDesc.name = Path.GetFileName(strAttachment);
                mapiFileDesc.path = strAttachment;
                Marshal.StructureToPtr(mapiFileDesc, (IntPtr)ptr, false);
                ptr += size;
            }

            fileCount = m_attachments.Count;
            return intPtr;
        }

        void Cleanup(ref MapiMessage msg)
        {
            int size = Marshal.SizeOf(typeof(MapiRecipDesc));
            int ptr = 0;

            if (msg.recips != IntPtr.Zero)
            {
                ptr = (int)msg.recips;
                for (int i = 0; i < msg.recipCount; i++)
                {
                    Marshal.DestroyStructure((IntPtr)ptr, 
                        typeof(MapiRecipDesc));
                    ptr += size;
                }
                Marshal.FreeHGlobal(msg.recips);
            }

            if (msg.files != IntPtr.Zero)
            {
                size = Marshal.SizeOf(typeof(MapiFileDesc));

                ptr = (int)msg.files;
                for (int i = 0; i < msg.fileCount; i++)
                {
                    Marshal.DestroyStructure((IntPtr)ptr, 
                        typeof(MapiFileDesc));
                    ptr += size;
                }
                Marshal.FreeHGlobal(msg.files);
            }
            
            m_recipients.Clear();
            m_attachments.Clear();
            m_lastError = 0;
        }
        
        public string GetLastError()
        {
            if (m_lastError <= 26)
                return errors[ m_lastError ];
            return "MAPI error [" + m_lastError.ToString() + "]";
        }

        readonly 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]" 
        };


        List<MapiRecipDesc> m_recipients    = new 
            List<MapiRecipDesc>();
        List<string> m_attachments    = new List<string>();
        int m_lastError = 0;

        const int MAPI_LOGON_UI = 0x00000001;
        const int MAPI_DIALOG = 0x00000008;
        const int maxAttachments = 20;

        enum HowTo{MAPI_ORIG=0, MAPI_TO, MAPI_CC, MAPI_BCC};
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public 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)]
    public class MapiFileDesc
    {
        public int reserved;
        public int flags;
        public int position;
        public string path;
        public string name;
        public IntPtr type;
    }

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public class MapiRecipDesc
    {
        public int        reserved;
        public int        recipClass;
        public string    name;
        public string    address;
        public int        eIDSize;
        public IntPtr    entryID;
    }
}

Here's the code for the C# class. If you compare it to the C++ version in my previous article, you'll see it's basically the same structure with a few additions to cope with the marshaling.

Sidebar

By managing its own memory, you can't just include the mapi.h in your .NET code to get the necessary MapiMessage and MapiFileDesc structures. I've just hand copied the ones I needed, but maybe someone will complete this chore or write a .h converter.

The VB.NET way

Here's the equivalent VB.NET class which doesn't really need any more explanation than given above:

Namespace SendFileTo
    Class MAPI
        Public Function AddRecipientTo(ByVal email As String) As Boolean
            Return AddRecipient(email, howTo.MAPI_TO)
        End Function

        Public Function AddRecipientCC(ByVal email As String) As Boolean
            Return AddRecipient(email, howTo.MAPI_TO)
        End Function

        Public Function AddRecipientBCC(ByVal email As String) As Boolean
            Return AddRecipient(email, howTo.MAPI_TO)
        End Function

        Public Sub AddAttachment(ByVal strAttachmentFileName As String)
            m_attachments.Add(strAttachmentFileName)
        End Sub

        Public Function SendMailPopup(ByVal strSubject As String, 
                ByVal strBody As String) As Integer
            Return SendMail(strSubject, strBody, MAPI_LOGON_UI Or MAPI_DIALOG)
        End Function

        Public Function SendMailDirect(ByVal strSubject As String, 
            ByVal strBody As String) As Integer
            Return SendMail(strSubject, strBody, MAPI_LOGON_UI)
        End Function


        <DllImport("MAPI32.DLL")> _
         Private Shared Function MAPISendMail(ByVal sess As IntPtr, 
             ByVal hwnd As IntPtr, ByVal message As MapiMessage, 
             ByVal flg As Integer, ByVal rsv As Integer) As Integer
        End Function

        Private Function SendMail(ByVal strSubject As String, 
            ByVal strBody As String, ByVal how As Integer) As Integer
            Dim msg As MapiMessage = New MapiMessage()
            msg.subject = strSubject
            msg.noteText = strBody

            msg.recips = GetRecipients(msg.recipCount)
            msg.files = GetAttachments(msg.fileCount)

            m_lastError = MAPISendMail(New IntPtr(0), New IntPtr(0), msg, how, 
                0)
            If m_lastError > 1 Then
                MessageBox.Show("MAPISendMail failed! " + GetLastError(), 
                    "MAPISendMail")
            End If

            Cleanup(msg)
            Return m_lastError
        End Function

        Private Function AddRecipient(ByVal email As String, 
            ByVal howTo As howTo) As Boolean
            Dim recipient As MapiRecipDesc = New MapiRecipDesc()

            recipient.recipClass = CType(howTo, Integer)
            recipient.name = email
            m_recipients.Add(recipient)

            Return True
        End Function

        Private Function GetRecipients(ByRef recipCount As Integer) As IntPtr
            recipCount = 0
            If m_recipients.Count = 0 Then
                Return 0
            End If

            Dim size As Integer = Marshal.SizeOf(GetType(MapiRecipDesc))
            Dim intPtr As IntPtr = Marshal.AllocHGlobal(
                m_recipients.Count * size)

            Dim ptr As Integer = CType(intPtr, Integer)
            Dim mapiDesc As MapiRecipDesc
            For Each mapiDesc In m_recipients
                Marshal.StructureToPtr(mapiDesc, CType(ptr, IntPtr), False)
                ptr += size
            Next

            recipCount = m_recipients.Count
            Return intPtr
        End Function

        Private Function GetAttachments(ByRef fileCount As Integer) As IntPtr
            fileCount = 0
            If m_attachments Is Nothing Then
                Return 0
            End If

            If (m_attachments.Count <= 0) Or (m_attachments.Count > 
                maxAttachments) Then
                Return 0
            End If

            Dim size As Integer = Marshal.SizeOf(GetType(MapiFileDesc))
            Dim intPtr As IntPtr = Marshal.AllocHGlobal(
                m_attachments.Count * size)

            Dim mapiFileDesc As MapiFileDesc = New MapiFileDesc()
            mapiFileDesc.position = -1
            Dim ptr As Integer = CType(intPtr, Integer)

            Dim strAttachment As String
            For Each strAttachment In m_attachments
                mapiFileDesc.name = Path.GetFileName(strAttachment)
                mapiFileDesc.path = strAttachment
                Marshal.StructureToPtr(mapiFileDesc, CType(ptr, IntPtr), False)
                ptr += size
            Next

            fileCount = m_attachments.Count
            Return intPtr
        End Function

        Private Sub Cleanup(ByRef msg As MapiMessage)
            Dim size As Integer = Marshal.SizeOf(GetType(MapiRecipDesc))
            Dim ptr As Integer = 0

            If msg.recips <> IntPtr.Zero Then
                ptr = CType(msg.recips, Integer)
                Dim i As Integer
                For i = 0 To msg.recipCount - 1 Step i + 1
                    Marshal.DestroyStructure(CType(ptr, IntPtr), 
                        GetType(MapiRecipDesc))
                    ptr += size
                Next
                Marshal.FreeHGlobal(msg.recips)
            End If

            If msg.files <> IntPtr.Zero Then
                size = Marshal.SizeOf(GetType(MapiFileDesc))

                ptr = CType(msg.files, Integer)
                Dim i As Integer
                For i = 0 To msg.fileCount - 1 Step i + 1
                    Marshal.DestroyStructure(CType(ptr, IntPtr), 
                        GetType(MapiFileDesc))
                    ptr += size
                Next
                Marshal.FreeHGlobal(msg.files)
            End If

            m_recipients.Clear()
            m_attachments.Clear()
            m_lastError = 0
        End Sub

        Public Function GetLastError() As String
            If m_lastError <= 26 Then
                Return errors(m_lastError)
            End If
            Return "MAPI error [" + m_lastError.ToString() + "]"
        End Function

        ReadOnly errors() As String = 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]"}

        Dim m_recipients As New List(Of MapiRecipDesc)
        Dim m_attachments As New List(Of String)
        Dim m_lastError As Integer = 0

        Private Const MAPI_LOGON_UI As Integer = &H1
        Private Const MAPI_DIALOG As Integer = &H8
        Private Const maxAttachments As Integer = 20

        Enum howTo
            MAPI_ORIG = 0
            MAPI_TO
            MAPI_CC
            MAPI_BCC
        End Enum

    End Class

    <StructLayout(LayoutKind.Sequential)> _
    Public Class MapiMessage
        Public reserved As Integer
        Public subject As String
        Public noteText As String
        Public messageType As String
        Public dateReceived As String
        Public conversationID As String
        Public flags As Integer
        Public originator As IntPtr
        Public recipCount As Integer
        Public recips As IntPtr
        Public fileCount As Integer
        Public files As IntPtr
    End Class

    <StructLayout(LayoutKind.Sequential)> _
    Public Class MapiFileDesc
        Public reserved As Integer
        Public flags As Integer
        Public position As Integer
        Public path As String
        Public name As String
        Public type As IntPtr
    End Class

    <StructLayout(LayoutKind.Sequential)> _
    Public Class MapiRecipDesc
        Public reserved As Integer
        Public recipClass As Integer
        Public name As String
        Public address As String
        Public eIDSize As Integer
        Public enTryID As IntPtr
    End Class
End Namespace

Example use

The attached C# and VB.NET samples show the whole story, but to use this is pretty easy as this fragment shows:

Screenshot - SendToNET3.jpg

using SendFileTo;

namespace TestSendTo
{
    public partial class Form1 : Form
    {
        private void btnSend_Click(object sender, EventArgs e)
        {
            MAPI mapi = new MAPI();

            mapi.AddAttachment("c:\\temp\\file1.txt");
            mapi.AddAttachment("c:\\temp\\file2.txt");
            mapi.AddRecipientTo("person1@somewhere.com");
            mapi.AddRecipientTo("person2@somewhere.com");
            mapi.SendMailPopup("testing", "body text");
            
            // Or if you want try and do a direct send without displaying the 

            // mail dialog mapi.SendMailDirect("testing", "body text");

        }
    }
}

You can call AddAttachment and AddRecipient multiple times to add as many attachments and recipients as you want, although I've put an arbitrary limit of 20 on the attachments just as a precaution. Calling SendMailPopup will display the email client send mail dialog and you can then add further recipients or attachments and hit the send button manually. Alternatively, you can call SendMailDirect which will attempt to send the mail without showing the email client dialog.

Make sure when using the samples with hard coded attachment paths shown above that the files exist in the given locations. If you don't, SendMail will fail.

Errors

If the return value from the underlying MAPISendMail is anything other than OK[0] or User aborted[1], a message box will be displayed with the appropriate error text and code.

I cannot self-terminate. You must lower me into the steel.

Hopefully, this has answered all the questions although I'm sure there will be comments. I've been using the C# code in a few applications for remote bug reporting, and I haven't had any problems. Do let me know if you spot any howlers. I hope there aren't any, otherwise I'll have to stoop to an unworthy Rise Of The Email Attachments.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralHave a issue in windows XP 64bit system.
RulinHong
9:11 29 Jan '10  
Great Job.

when I set default mail client to Outlook express, it works both on windows XP 32bit and 64bit system. but when I set default mail client to Outlook 2007 on XP 64bit system, I get an exception:

See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at SendToVB.SendFileTo.MAPI.GetLastError() in D:\Temp\Mapi\SendToVB\SendToVB\SendFileTo.vb:line 149
at SendToVB.SendFileTo.MAPI.SendMail(String strSubject, String strBody, Int32 how) in D:\Temp\Mapi\SendToVB\SendToVB\SendFileTo.vb:line 50
at SendToVB.Form1.btnSend_Click(Object sender, EventArgs e) in D:\Temp\Mapi\SendToVB\SendToVB\Form1.vb:line 28
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.3603 (GDR.050727-3600)
CodeBase: file:///c:/WINDOWS/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
----------------------------------------
SendToVB
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///X:/Rulin/SendToVB.exe
----------------------------------------
Microsoft.VisualBasic
Assembly Version: 8.0.0.0
Win32 Version: 8.0.50727.3053 (netfxsp.050727-3000)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualBasic/8.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
----------------------------------------
System
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.3053 (netfxsp.050727-3000)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Windows.Forms
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.3053 (netfxsp.050727-3000)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.3053 (netfxsp.050727-3000)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.3053 (netfxsp.050727-3000)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.3082 (QFE.050727-3000)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Runtime.Remoting
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.3053 (netfxsp.050727-3000)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Runtime.Remoting/2.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.

www

GeneralSome Bug
jffry2
7:15 25 Nov '09  
m_lastError = MAPISendMail(new IntPtr(0), new IntPtr(0), msg, how, 0);
....
return m_lastError;

Returns always 0, because Cleanup() changes lastError...

I changed to:
int nRet = 0;
...
nRet = m_lastError = MAPISendMail(new IntPtr(0), new IntPtr(0), msg, how, 0);
....
return nRet;

Or reset lastError from nRet or change Cleanup or D'Oh!
GeneralSender Class
cjbarth
15:20 22 Oct '09  
I've modified your code to provide a class to actually do the email sending so that others can use your program much more easily. If you would like what I wrote so you can update your article I would be happy to share it with you.
GeneralSaving a .msg file
hugomau
6:47 21 Sep '09  
Hi,

First of all, great and useful article.

Is there a way to use MAPI32.DLL to creat a .msg file and save it in the hard-disk?

Thanks,

Hugo Maurício
Generalunable to send the message
rikki233752
19:29 20 Sep '09  
i m not being to send the message because the send tool bar is displaying message cant be send
Questionnot working for window live mail any help?
Can Gunaydin
0:56 3 Sep '09  
hi,
thank you for this great code,i am using this class in my .Net application, it was perfectly working on my client's notebook when he was using outlook express but he changed his email program to windows live mail and now when he tried to send mail via my application only windows live mail is opening up and nothing happens. It couldn't create the new mail message popup and attachents. Do you have any idea why is this happening? any help would be appreciated. Thank you.
GeneralNice Code
_WinBase_
1:15 27 Aug '09  
Just what i was looking for tx

Bob
GeneralAttaching files containing UTF-8 characters (like hebrew)
silver82
15:06 22 Aug '09  
I am unable to attach those files, I was wondering if you could give me a head start on where to look. Tried to modify the character encoding in the class to UTF, still no go. And it's the same if I want to put hebrew content in body (if I switch to UTF it shows different text but not hebrew).
GeneralHow to know if email client is closed or send message?
marcoscavaleiro
5:25 18 Jun '09  
Hi, this is great!!!

How can i know if the user click the "X" close button or click send mail??

I thinks it's not possible..The threat state is always Stoped in the two cases..

Thanks
GeneralGreat code, question regarding including signatures
NathanKoop
11:50 5 Jun '09  
Hello,

I am trying to include the user's default signature in the email.

Is this possible, if so, could you point me in the right direction.

Thanks,

Nathan
GeneralDoes not work
E.Glashagen
4:22 1 Jun '09  
When trying the sample, the client(Outlook 2003) comes up. But when I click the send-button nothing happens. The client remains on the desktop. The e,ail cannot be send. Has Somebody also determined this behavior and is there a solution?

Greetings
Erich
GeneralMAPI communicate with Exchange Server.
rotiegg
22:50 31 May '09  
Hey David,

Well done! You give me a good start on using mapi32.dll in C#, which i couldn't find a easy and simple one over the internet. Thanks in advance! Laugh

One question here: As what you use as an example here is <b>MAPISendMail(IntPtr sess, IntPtr hwnd, MapiMessage message, int flg, int rsv);</b>
How are we going to know what else funtions are provided in MAPI32.DLL? What are their parameters?

I am actually developing an application which communicate (more to calendar) with Exchange Server 2003. I need the functions to request, cancel, delete the meeting from the Exchange, without installing the Outlook. Is it possible for me to use mapi32.dll with Platform invoke (as what you shown) for my task?

It is the best if you could navigate or consult me how it works.
Appreciate you help very much.

Thanks,
Hua
GeneralWorked great, simple, easy to use
Paul B.
12:48 11 May '09  
.
QuestionIs there a way to save a message sent by MAPISendMail in the Sent Items folder?
Max Rudoi
4:21 4 May '09  
Hi David,
I noticed that after a message is sent it is not saved in the Sent Mail folder. Is there a way to do it?
Questionnot going to default email client
nina98765
19:33 16 Mar '09  
hi, i've implemented this code, and put it out on several machines. on one of the machines there are both outlook express and outlook installed. outlook express is set up as the default email client but the emails from my program (using this code) are going to outlook instead. any ideas?
Questionhtml message
sammygth
4:56 2 Mar '09  
Hi,
Enyone knows how can i send a html mail message.
Thanks.
GeneralRe: html message
xavierakx
16:51 26 Apr '09  
Read this :
http://support.microsoft.com/kb/268440[^]

Xavier
QuestionOne or more parts of this message could not be displayed
Member 2655509
7:02 11 Feb '09  
I've compiled an application that uses this code, that generates PDF documents and attempts to attach them to emails; and it seems to work on "established" systems. I've seen it work on Outlook Express, Thunderbird, and Windows Live Mail without an issue.

However, when I try to run the program on a vanilla XP installation in a virtual machine (which I do for testing -- it is, unfortunately, also what my client is now doing since he recently purchased a Mac and is running an XP session in VMWare), the installation of Outlook Express (even when configured to send and receive email normally) will fail with the message "One or more parts of this message could not be displayed" when I try to do a SendMailPopup.

I've tried installing IE7 (thinking it might update OE) and Adobe Acrobat (since I'm attaching PDFs), but the message persists.

Any ideas? I'm stumped.
AnswerRe: One or more parts of this message could not be displayed
_Flyer_
6:06 28 Sep '09  
It message shown, when I call MAPISendMail in C# console application or in not-main thread of windows application.
GeneralCode doesn't work on a web app using IIS
iiiiii168
6:07 14 Jan '09  
Hi, did anybody get this code work on a web app using IIS? it does work using a file system, but not on IIS. any idea? Please help!
QuestionMAPISendMail returns General MAPI failure
MeNot
3:30 6 Jan '09  
Hi David,

thanks for the great article. I've run your testapp and encountered a little problem:

MAPISendMail returns 2 (General MAPI failure). Can you tell me how to troubleshoot this error?

Cheers
Stefan


AnswerTry to check your machine configuration
Max Rudoi
2:47 4 May '09  
I got the same error message when the project compiled in VS2003 with Framework 1.1 was launched on a different machine that had both Framework 1.1 and Framework 2.0
It worked only on a machine with Framework 1.1

The project compiled in VS2005 worked fine on the machine with both Framework 1.1 and Framework 2.0

You might try to check your machine configuration to see if it's the same kind of problem.
AnswerRe: MAPISendMail returns General MAPI failure
Eilens
0:41 11 Aug '09  
Hi,

try to set the STAThread-attribute on your Main-method. That solved the problem for me.
Generalsendmailpopup not working with asp.net 2008
dianec
9:11 3 Dec '08  
I tried to use this code, and works fine with window, but failed when I call it from aspx page (the page refresh, but not launch the client default mail outlook) I did include AspCompat="true" in the page directive.... please help.
GeneralWell Done
TheJaffe
6:12 13 Nov '08  
I have been looking for a nice simple class like this for some time. I read a number of other articles with horifically complex implementations. I dropped this into my app and it worked no problem.


Last Updated 20 Apr 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010