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 Microsoft.Office.Interop.Outlook.Application
namespace but it opens outlook and wont work if outlook is not installed on the client's computer.
I tried using SmtpClient()
and MailMessage()
classes of System.Net.Mail
namespace but its not opening email client. Its sending a mail through predefined server (might be a problem since I don't know what my client's default email domain is. This link has all the things I need and its working fine.
But there they used DllImport attribute and there are many issues that may arise (from what I can understand) from using this method. I have no idea about managed and un-managed code so I am not able to understand what the problem is. Is it OK to follow the example in the above link. If not why?
Can you tell or provide links on how to approach my problem
Open Outlook. On the Tools menu, click Options, and then click the Other tab. Under General, select the Make Outlook the default program for E-mail, Contacts, and Calendar check box. Click OK.
The default mail program is the software that is registered with your operating system as the software that is to handle mailto URL's. When another application wants to send an email, it looks up the default and passes the email to the default mail program.
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("[email protected]"); mailMessage.Subject = "Your subject here"; mailMessage.IsBodyHtml = true; mailMessage.Body = "<span style='font-size: 12pt; color: red;'>My HTML formatted body</span>"; 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);
Have you tried using System.Diagnostics.Process.Start()
with an appropriate command line?
mailto:[email protected]?subject=an email&body=see attachment&attachment="/files/audio/attachment.mp3"
The &attachment
switch lets you specify a file name.
Ok, I'm struggling to this working but allegedly it can be done. I'm currently reading through this monster and will get back to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With