using System.Diagnostics; using System.IO; using System.Net.Mail; using System.Reflection; using System.Text; using InABox.Clients; using InABox.Core; namespace PRS.Shared { public class EmailUtils { /// /// Creates and opens an email with the default email app - selected by the user. /// This method is for emails with a PDF attachment. Provide the file name and data. /// Optionally provide from, subject and body. /// If from is not provided, an attempt will be made to find the User's email address - if empty it will throw an error (cannot be empty) /// /// /// /// /// /// public static void CreateEMLFile(string attachmentname, byte[] attachmentdata, string from = "", string subject = "", string body = "", string to = "") { var message = CreateMessage(from, subject, body, to); message = AddAttachment(message, attachmentname, attachmentdata); OpenEmail(message, attachmentname); } /// /// Creates and opens an email with the default email app - selected by the user. /// This method is for emails with no attachments. /// Optionally provide from, subject and body. /// If from is not provided, an attempt will be made to find the User's email address - if empty it will throw an error (cannot be empty) /// /// /// /// public static void CreateEMLFile(string from = "", string subject = "", string body = "") { var message = CreateMessage(from, subject, body); OpenEmail(message, "Message from " + from); } private static void OpenEmail(MailMessage message, string name) { var filename = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(name, ".eml")); using (var filestream = File.Open(filename, FileMode.Create)) { 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(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 mailWriterConstructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(Stream), typeof(bool) }, null)!; // Construct MailWriter object with our FileStream var mailWriter = mailWriterConstructor.Invoke(new object[] { filestream, true }); // 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[] { 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); } // Open the file with the default associated application registered on the local machine Process.Start(new ProcessStartInfo(filename) { UseShellExecute = true }); } private static MailMessage CreateMessage(string from, string subject, string body, string to = "") { if (string.IsNullOrWhiteSpace(to)) to = "example@outlook.com.au"; if (string.IsNullOrWhiteSpace(from)) from = GetAddressFromUser(); if (string.IsNullOrWhiteSpace(subject)) subject = "Enter subject"; if (string.IsNullOrWhiteSpace(body)) body = "Enter message"; var message = new MailMessage(from, to, subject, body); message.IsBodyHtml = false; return message; } private static string GetAddressFromUser() { CoreTable table = new Client().Query(new Filter(x => x.ID).IsEqualTo(ClientFactory.UserGuid) , new Columns(x => x.EmailAddress)); User user = table.Rows.FirstOrDefault().ToObject(); if (!string.IsNullOrWhiteSpace(user.EmailAddress)) return user.EmailAddress; else MessageBox.Show("Current User Email Address is blank - please fill in (Human Resources -> User Accounts -> Choose your User -> Email Settings -> Email Address", "Error"); return ""; } private static MailMessage AddAttachment(MailMessage message, string attachmentname, byte[] attachmentdata) { var attachment = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(attachmentname, ".pdf")); File.WriteAllBytes(attachment, attachmentdata); message.Attachments.Add(new Attachment(attachment)); return message; } } }