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;
}
}
}