EmailUtils.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. 
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Net.Mail;
  5. using System.Reflection;
  6. using System.Text;
  7. using InABox.Clients;
  8. using InABox.Core;
  9. namespace PRS.Shared
  10. {
  11. public class EmailUtils
  12. {
  13. /// <summary>
  14. /// Creates and opens an email with the default email app - selected by the user.
  15. /// This method is for emails with a PDF attachment. Provide the file name and data.
  16. /// Optionally provide from, subject and body.
  17. /// 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)
  18. /// </summary>
  19. /// <param name="attachmentname"></param>
  20. /// <param name="attachmentdata"></param>
  21. /// <param name="from"></param>
  22. /// <param name="subject"></param>
  23. /// <param name="body"></param>
  24. public static void CreateEMLFile(string attachmentname, byte[] attachmentdata, string from = "", string subject = "", string body = "")
  25. {
  26. var message = CreateMessage(from, subject, body);
  27. message = AddAttachment(message, attachmentname, attachmentdata);
  28. OpenEmail(message, attachmentname);
  29. }
  30. /// <summary>
  31. /// Creates and opens an email with the default email app - selected by the user.
  32. /// This method is for emails with no attachments.
  33. /// Optionally provide from, subject and body.
  34. /// 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)
  35. /// </summary>
  36. /// <param name="from"></param>
  37. /// <param name="subject"></param>
  38. /// <param name="body"></param>
  39. public static void CreateEMLFile(string from = "", string subject = "", string body = "")
  40. {
  41. var message = CreateMessage(from, subject, body);
  42. OpenEmail(message, "Message from " + from);
  43. }
  44. private static void OpenEmail(MailMessage message, string name)
  45. {
  46. var filename = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(name, ".eml"));
  47. using (var filestream = File.Open(filename, FileMode.Create))
  48. {
  49. var binaryWriter = new BinaryWriter(filestream);
  50. //Write the Unsent header to the file so the mail client knows this mail must be presented in "New message" mode
  51. binaryWriter.Write(Encoding.UTF8.GetBytes("X-Unsent: 1" + Environment.NewLine));
  52. var assembly = typeof(SmtpClient).Assembly;
  53. var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter")!;
  54. // Get reflection info for MailWriter contructor
  55. var mailWriterConstructor =
  56. mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(Stream), typeof(bool) }, null)!;
  57. // Construct MailWriter object with our FileStream
  58. var mailWriter = mailWriterConstructor.Invoke(new object[] { filestream, true });
  59. // Get reflection info for Send() method on MailMessage
  60. var sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic)!;
  61. sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null);
  62. // Finally get reflection info for Close() method on our MailWriter
  63. var closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic)!;
  64. // Call close method
  65. closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);
  66. }
  67. // Open the file with the default associated application registered on the local machine
  68. Process.Start(new ProcessStartInfo(filename) { UseShellExecute = true });
  69. }
  70. private static MailMessage CreateMessage(string from, string subject, string body)
  71. {
  72. var message = new MailMessage();
  73. if (string.IsNullOrWhiteSpace(from))
  74. from = GetAddressFromUser();
  75. message.From = new MailAddress(from);
  76. message.Subject = subject;
  77. message.IsBodyHtml = true;
  78. message.Body = body;
  79. return message;
  80. }
  81. private static string GetAddressFromUser()
  82. {
  83. CoreTable table = new Client<User>().Query(new Filter<User>(x => x.ID).IsEqualTo(ClientFactory.UserGuid)
  84. , new Columns<User>(x => x.EmailAddress));
  85. User user = table.Rows.FirstOrDefault().ToObject<User>();
  86. if (!string.IsNullOrWhiteSpace(user.EmailAddress))
  87. return user.EmailAddress;
  88. else
  89. MessageBox.Show("Unable to send email. Current User Email Address is blank - please fill in", "Error");
  90. return "";
  91. }
  92. private static MailMessage AddAttachment(MailMessage message, string attachmentname, byte[] attachmentdata)
  93. {
  94. var attachment = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(attachmentname, ".pdf"));
  95. File.WriteAllBytes(attachment, attachmentdata);
  96. message.Attachments.Add(new Attachment(attachment));
  97. return message;
  98. }
  99. }
  100. }