EmailUtils.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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 = "", string to = "")
  25. {
  26. var message = CreateMessage(from, subject, body, to);
  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, string to = "")
  71. {
  72. if (string.IsNullOrWhiteSpace(to))
  73. to = "example@outlook.com.au";
  74. if (string.IsNullOrWhiteSpace(from))
  75. from = GetAddressFromUser();
  76. if (string.IsNullOrWhiteSpace(subject))
  77. subject = "Enter subject";
  78. if (string.IsNullOrWhiteSpace(body))
  79. body = "Enter message";
  80. var message = new MailMessage(from, to, subject, body);
  81. message.IsBodyHtml = false;
  82. return message;
  83. }
  84. private static string GetAddressFromUser()
  85. {
  86. CoreTable table = new Client<User>().Query(new Filter<User>(x => x.ID).IsEqualTo(ClientFactory.UserGuid)
  87. , new Columns<User>(x => x.EmailAddress));
  88. User user = table.Rows.FirstOrDefault().ToObject<User>();
  89. if (!string.IsNullOrWhiteSpace(user.EmailAddress))
  90. return user.EmailAddress;
  91. else
  92. MessageBox.Show("Current User Email Address is blank - please fill in (Human Resources -> User Accounts -> Choose your User -> Email Settings -> Email Address", "Error");
  93. return "";
  94. }
  95. private static MailMessage AddAttachment(MailMessage message, string attachmentname, byte[] attachmentdata)
  96. {
  97. var attachment = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(attachmentname, ".pdf"));
  98. File.WriteAllBytes(attachment, attachmentdata);
  99. message.Attachments.Add(new Attachment(attachment));
  100. return message;
  101. }
  102. }
  103. }