| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 | 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;using System.Diagnostics.CodeAnalysis;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        };    }    public static string GetAddressFromUser()    {        if(TryGetAddressFromUser(out var address))        {            return address;        }        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 string? GetAddressFromUserOrNull()    {        TryGetAddressFromUser(out var address);        return address;    }    public static bool TryGetAddressFromUser([NotNullWhen(true)] out string? address)    {        var table = Client.Query(new Filter<User>(x => x.ID).IsEqualTo(ClientFactory.UserGuid), Columns.None<User>().Add(x => x.EmailAddress));        var user = table.ToObjects<User>().FirstOrDefault();        address = user?.EmailAddress.NotWhiteSpaceOr(null);        return address is not null;    }    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;    }}
 |