|
@@ -0,0 +1,163 @@
|
|
|
+using InABox.Clients;
|
|
|
+using InABox.Core;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Diagnostics;
|
|
|
+using System.IO;
|
|
|
+using System.Linq;
|
|
|
+using System.Net.Mail;
|
|
|
+using System.Reflection;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using System.Windows.Controls;
|
|
|
+using System.Windows;
|
|
|
+using System.Windows.Forms;
|
|
|
+using System.Drawing;
|
|
|
+using InABox.WPF;
|
|
|
+using MessageBox = System.Windows.Forms.MessageBox;
|
|
|
+using TextBox = System.Windows.Controls.TextBox;
|
|
|
+using InABox.Wpf.Reports;
|
|
|
+
|
|
|
+namespace InABox.Wpf;
|
|
|
+
|
|
|
+public static class EmailUtils
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// 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)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="attachmentname"></param>
|
|
|
+ /// <param name="attachmentdata"></param>
|
|
|
+ /// <param name="from"></param>
|
|
|
+ /// <param name="subject"></param>
|
|
|
+ /// <param name="body"></param>
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Creates and opens an email with the default email app - selected by the user.
|
|
|
+ /// This method is for emails with multiple PDF attachments. Provide the a Dictionary of names and byte arrays
|
|
|
+ /// 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)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="attachmentname"></param>
|
|
|
+ /// <param name="attachmentdata"></param>
|
|
|
+ /// <param name="from"></param>
|
|
|
+ /// <param name="subject"></param>
|
|
|
+ /// <param name="body"></param>
|
|
|
+ public static void CreateEMLFile(Dictionary<string,byte[]> attachments, string from = "", string subject = "", string body = "", string to = "")
|
|
|
+ {
|
|
|
+ var message = CreateMessage(from, subject, body, to);
|
|
|
+
|
|
|
+ foreach (var key in attachments.Keys)
|
|
|
+ AddAttachment(message, key, attachments[key]);
|
|
|
+
|
|
|
+ OpenEmail(message);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 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)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="from"></param>
|
|
|
+ /// <param name="subject"></param>
|
|
|
+ /// <param name="body"></param>
|
|
|
+
|
|
|
+ public static void CreateEMLFile(string? from, string? subject, string? body)
|
|
|
+ {
|
|
|
+ var message = CreateMessage(from, subject, body);
|
|
|
+
|
|
|
+ OpenEmail(message, "Message from " + message.From);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void OpenEmail(MailMessage message, string? name = null)
|
|
|
+ {
|
|
|
+ var filename = Path.Combine(
|
|
|
+ Path.GetTempPath(),
|
|
|
+ Path.ChangeExtension(String.IsNullOrWhiteSpace(name) ? Guid.NewGuid().ToString() : 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 });
|
|
|
+ }
|
|
|
+
|
|
|
+ public static MailMessage CreateMessage(string? from = null, string? subject = null, string? body = null, string? to = null)
|
|
|
+ {
|
|
|
+ return new MailMessage(
|
|
|
+ from.NotWhiteSpaceOr(GetAddressFromUser()).NotWhiteSpaceOr("example@outlook.com.au"),
|
|
|
+ to.NotWhiteSpaceOr("example@outlook.com.au"),
|
|
|
+ subject.NotWhiteSpaceOr("Enter subject"),
|
|
|
+ body.NotWhiteSpaceOr("Enter message"))
|
|
|
+ {
|
|
|
+ IsBodyHtml = false
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string GetAddressFromUser()
|
|
|
+ {
|
|
|
+ CoreTable table = new Client<User>().Query(new Filter<User>(x => x.ID).IsEqualTo(ClientFactory.UserGuid)
|
|
|
+ , new Columns<User>(x => x.EmailAddress));
|
|
|
+ User user = table.Rows.FirstOrDefault().ToObject<User>();
|
|
|
+
|
|
|
+ if (!string.IsNullOrWhiteSpace(user.EmailAddress))
|
|
|
+ return user.EmailAddress;
|
|
|
+ else
|
|
|
+ MessageWindow.ShowMessage("Current User Email Address is blank - please fill in (Human Resources -> User Accounts -> Choose your User -> Email Settings -> Email Address", "Error");
|
|
|
+
|
|
|
+ return "";
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public static MailMessage AddAttachment(this MailMessage message, string attachmentname, byte[] attachmentdata)
|
|
|
+ {
|
|
|
+ var attachment = Path.Combine(
|
|
|
+ Path.GetTempPath(),
|
|
|
+ String.IsNullOrWhiteSpace(Path.GetExtension(attachmentname))
|
|
|
+ ? Path.ChangeExtension(attachmentname, ".pdf")
|
|
|
+ : attachmentname
|
|
|
+ );
|
|
|
+ File.WriteAllBytes(attachment, attachmentdata);
|
|
|
+
|
|
|
+ message.Attachments.Add(new Attachment(attachment));
|
|
|
+
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+}
|