Open default mail client along with a attachment

前端 未结 4 952
生来不讨喜
生来不讨喜 2020-11-27 18:10

Hi I am working on a WPF application (using c#).

I need to have a functionality where users can send files (audio files) as attachments via email. I tried using

4条回答
  •  一向
    一向 (楼主)
    2020-11-27 19:08

    We can make use of the fact that most email clients support the .EML file format to be loaded.

    So if we Extend the System.Net.Mail.MailMessage Class in a way that it can be saved to the filesystem as an .EML file. The resulting file can be opened with the default mail client using Process.Start(filename)

    For this to work properly we have to add a line containing "X-Unsent: 1" to the .EML file. This line tells the email client loading the .EML file the message must be presented in "New message" mode.

    Use the "addUnsentHeader" bool parameter of the extension method to add this line to the .EML file

    The extension method looks like this:

    using System;
    using System.IO;
    using System.Net.Mail;
    using System.Reflection;
    
    namespace Fsolutions.Fbase.Common.Mail
    {
        public static class MailUtility
        {
            //Extension method for MailMessage to save to a file on disk
            public static void Save(this MailMessage message, string filename, bool addUnsentHeader = true)
            {
                using (var filestream = File.Open(filename, FileMode.Create))
                {
                    if (addUnsentHeader)
                    {
                        var binaryWriter = new BinaryWriter(filestream);
                        //Write the Unsent header to the file so the mail client knows this mail must be presented in "New message" mode
                        binaryWriter.Write(System.Text.Encoding.UTF8.GetBytes("X-Unsent: 1" + Environment.NewLine));
                    }
    
                    var assembly = typeof(SmtpClient).Assembly;
                    var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
    
                    // Get reflection info for MailWriter contructor
                    var mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
    
                    // Construct MailWriter object with our FileStream
                    var mailWriter = mailWriterContructor.Invoke(new object[] { filestream });
    
                    // Get reflection info for Send() method on MailMessage
                    var sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);
    
                    sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { mailWriter, true, true }, null);
    
                    // Finally get reflection info for Close() method on our MailWriter
                    var closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic);
    
                    // Call close method
                    closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);
                }
            }
        }
    }
    

    Use the extension method like this:

            var mailMessage = new MailMessage();
            mailMessage.From = new MailAddress("someone@yourdomain.com");
            mailMessage.Subject = "Your subject here";
            mailMessage.IsBodyHtml = true;
            mailMessage.Body = "My HTML formatted body";
    
            mailMessage.Attachments.Add(new Attachment("C://Myfile.pdf"));
    
            var filename = "C://Temp/mymessage.eml";
    
            //save the MailMessage to the filesystem
            mailMessage.Save(filename);
    
            //Open the file with the default associated application registered on the local machine
            Process.Start(filename);
    

提交回复
热议问题