Sending files via the default e-mail client

I recently released a "Send To Email" plugin for Cropper, which makes it easy to grab a portion of your screen and send it as an e-mail attachment. It's easy enough to directly send an e-mail in .NET using System.Net.Mail, but there's no provision for sending a mail using the default client.

Spoiler - if you just want the code without the background, skip to the "Take Three" section below.

Take One - MailTo link

You can launch the default mail client by shelling out to a mailto link, and some e-mail Cropper - Send To Emailclients support an "attach" parameter:

mailto:dvader@deathstar.mil
?Subject=Rebel+Base+Detected
&Body=See+attached+pictures
&Attach="C:\Users\Fett\RebelBase[1].png

public static void Main() { SendMailWithMailTo( "dvader@deathstar.mil", "Rebel Base Detected", "Hoth, baybee!!", "\"C:\\Users\\Fett\\RebelBase[1].png\""); } public static void SendMailWithMailTo( string address, string subject, string body, string attach) { //Don't use this - just an example string mailto = string.Format( "mailto:{0}?Subject={1}&Body={2}&Attach={3}", address,subject,body,attach); System.Diagnostics.Process.Start(mailto); }

That's not really a good plan, though. The main reason is that the "attach" is an unofficial extension to the mailto protocol. It's not supported in a lot of e-mail clients, and those that implement it all work a little differently (for instance, some use "attachment" instead of "attach". I'd expect that fewer mail clients will be support attachments in the mailto protocol due to the obvious security issues (a mailto link on a website with an attachment reference to files in common locations, for instance). There was a security advisory for mailto attachments in Outlook 2003, for instance.

Take Two - Call MapiSendMail via PInvoke

MapiSendMail invokes the default e-mail client and supports attachments. There's a CodeProject article with C++ code, and the author supplied C# code to call MapiSendMail in the comments. It's reasonably straightforward, and it's easy to use. I'm going to skip over it, though, because it has one major problem - the call to MapiSendMail is modal. What that means is that your program hangs until the user edits and sends the e-mail. That's not at all what you'd expect as an end user - I'd want to be able to save the message as a draft and go on using the program.

Take Three - Call MapiSendMail Asynchronously

Andrew Baker's MAPI wrapper class does a great job of sending mail using the default e-mail client, and it does it asynchronously. The function you'll call, ShowDialog, just calls internal utility functions on a new thread and returns. It's very easy to use:

MapiMailMessage message = new MapiMailMessage(subject, body); message.Files.Add(file); message.ShowDialog();

20 Comments

  • Nice... Thanks for posting this...

  • THe information was useful, but it does not appear to work in a web application. I am still doing some testing with it, but so far when the application is deployed to the web server it will not call up the clients email application.

    When running it locally it does fine.

  • Works great! But I have one additional requirements: place images in the email body. I assume it would be done by using and tag somehow. But simply adding an doesn't work. Any ideas on how adding images to the body might be accomplished?

  • This is excellent, just what I've been looking for! I was originally sending the request by using outlook's command-line switches, but as soon as the requirement for supporting multiple clients came along, that went out the window!

  • hi, I tried the above and it does not seem to work in a web application i created in vs2003. can some one help??

  • Hi,
    I want to open default mail client and want to send mail in Html format, and want to embed image also.

  • Hi,
    Thanks for solving my problem....

  • Only works with local machine but does not work when deployed to webserver.

    Thanks
    Shafiq

  • i want to pass the from and url of the attachment as parameters of the function when i execute the exe. how should i do this

  • I am using Lotus Notes 6. This code is working perfectly on Ms Outlook and Outlook Express but not in Lotus Notes. You need to do a small modifiation to make it work in Lotus Notes. This code is cool!

  • Hi,
    this code was not working with IIS.

    What changes do we need to do to work in IIS

  • This cannot be done with a web application. Naturally it is not secure to be able to launch the e-mail client of anyone who visits your web page with an attachment from your server. It is not possible, sorry.

  • Hey It brings me a confidence tht..this forum will solve my problem..
    My Requirement is -
    In mailto body attribute : I need a HTML body with images and a link inside it.

    Any help..?

  • namespace Adastra.FrodMgmt.CommonUI.BusinessModel
    {
    public class MessageSentEventArgs
    {
    public static readonly MessageSentEventArgs Empty;
    public bool CancelPressed { get; set; }
    public MessageSentEventArgs(bool bCancelPressed)
    {
    this.CancelPressed = bCancelPressed;
    }
    }

    ///
    /// Provides functionality so Outlook can be used to generate Emails. Use the
    /// write event to log the email.
    ///
    /// Email outlookMsg = new Email();
    /// outlookMsg.Message.Subject = "Foo bar";
    /// outlookMsg.Show();
    ///
    ///
    public class Email
    {
    #region | Enents |

    public delegate void MessageSentEventHandlerCallBack(object sender, MessageSentEventArgs e);
    public event MessageSentEventHandlerCallBack MessageSent;

    #endregion //| Enents |

    #region | Instance variables |
    ///
    /// Gets the current instance of Outlook
    ///
    private OutlookApp.Application m_outlookInstance = new Microsoft.Office.Interop.Outlook.Application();

    public OutlookApp.MailItem Message { get; set; }

    #endregion //| Instance variables |

    #region | Constructor stuff |
    ///
    /// Constructor, gets current outlook instance
    /// and creates a blank email message
    ///
    public Email()
    {
    Initialize();
    }

    ///
    /// Initialize object
    ///
    private void Initialize()
    {
    //### Create a blank email
    this.Message = (OutlookApp.MailItem)m_outlookInstance.CreateItem(OutlookApp.OlItemType.olMailItem);

    //### Wire up the write event for logging
    this.Message.Write += new Microsoft.Office.Interop.Outlook.ItemEvents_10_WriteEventHandler(Message_Write);
    }

    #endregion //| Constructor stuff |

    #region | Email interface |
    ///
    /// Create email message and open MS Outlook pane
    ///
    /// address TO send

    /// address carbon copy to send

    /// flag if mail body is in html format

    /// flag if mail ha importance high

    /// message body

    public void Send(string strAddressTo,
    string strAddressCC,
    string strSubject,
    bool bIsHtml,
    bool bIsImportanceHigh,
    string strMessageBody,
    MessageSentEventHandlerCallBack messageSentEventHandler)
    {
    if (null != messageSentEventHandler)
    {
    this.MessageSent += new MessageSentEventHandlerCallBack(messageSentEventHandler);
    }
    this.Message.To = strAddressTo;
    this.Message.CC = strAddressCC;
    this.Message.Subject = strSubject;
    this.IsHtml = bIsHtml;
    this.IsImportanceHigh = bIsImportanceHigh;
    if(bIsHtml)
    {
    this.Message.HTMLBody = strMessageBody;
    }
    else
    {
    this.Message.Body = strMessageBody;
    }
    this.Show();
    }

    ///
    /// Get/Set flag if email body is HTML
    ///
    public bool IsHtml
    {
    get { return (Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML == this.Message.BodyFormat); }
    set { this.Message.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML; }
    }

    ///
    /// Get/Set flag if email importance is high
    ///
    public bool IsImportanceHigh
    {
    get { return (Microsoft.Office.Interop.Outlook.OlImportance.olImportanceHigh == this.Message.Importance); }
    set { this.Message.Importance = Microsoft.Office.Interop.Outlook.OlImportance.olImportanceHigh; }
    }

    ///
    /// Used for logging after the end user presses the send
    /// button in Outlook. If you need to log the email that was
    /// sent to a web service or something else, fill this in. This is
    /// called after the email is sent via Outlook.
    ///
    ///

    private void Message_Write(ref bool bCancel)
    {
    if (null != this.MessageSent)
    {
    this.MessageSent(this, new MessageSentEventArgs(bCancel));
    }
    }

    ///
    /// Displays the outlook screen and shows the email message.
    ///
    public void Show()
    {
    this.Message.Display(false);
    }

    #endregion //| Email interface |
    }
    }

  • It's not work with outlook 2003 2007

  • What should I do to modify it to work on Lotus Notes?

  • Please let me know how this should be applied for Web applications. I have a task of sending a pdf file from server to attach it to a mail and send it with Subject Message/Body and Signature. Please Provide me with whole code. Thanks....

    Pradeep

  • its not working :D

  • Good morning, is there an option in HTML mailto command that allows you to insert the default signature set in OLK?
    If I publish a mailto link in a web page I can send in the body message only the text I have set in body="...." command.
    Thank you.

  • What I want to do is different from those of others.I have a surprise for you.Mother doesn't make up.They are arguing over who should pay the bill.I have something to tell you.On being introduced to somebody, a British person often shakes hands.On being introduced to somebody, a British person often shakes hands.Neither you nor he is wrong.That's the latest fashion.I borrowed a notebook from Tom and I lent it to Marry.

Comments have been disabled for this content.