When I send emails with attachments they are correctly sent and I can see them in most clients but the paperclip is not showing.
Outlook shows this behaviour.
This wouldnt be a big problem if wheren't for other email clients like "bluewin.ch" where it doesn't even show the attachments when the paperclip is not available.
EML Builder code:
public static class EmlBuilder {
private const string NewLine = "\r\n";
/// <summary>
/// Builds and .eml File https://en.wikipedia.org/wiki/MIME#Content-Type
/// Opens it
/// And cleans up the temporary file as soon as it isn't needed anymore
/// </summary>
public static void BuildAndOpen(string receiver = null, string subject = null, string signature = null, params string[] attachments) {
//header
var version = "MIME-VERSION: 1.0";
var draftFlag = $"X-Unsent: {true.ToInt()}";
var from = "From: <>";
var xReceiver = $"X-Receiver: {receiver}";
var to = $"To: {receiver}";
var subj = $"Subject: {subject}";
//boundaries
var boundary = $"frontier";
var contentType = $"Content-Type: multipart/mixed; boundary={boundary}";
var boundaryLine = $"--{boundary}";
//header-content
var headerContent = string.Empty;
headerContent = version NewLine;
headerContent = draftFlag NewLine;
headerContent = contentType NewLine;
headerContent = from NewLine;
if (subject.IsDefined()) {
headerContent = subj NewLine;
}
if (receiver.IsDefined()) {
headerContent = xReceiver NewLine;
headerContent = to NewLine;
}
//between header and body
var headerBodyBoundary = string.Empty;
headerBodyBoundary = boundaryLine NewLine;
headerBodyBoundary = "Content-Type: text/html" NewLine;
//body-content
var bodyContent = string.Empty;
bodyContent = string.Empty NewLine; //TODO settings
//add signature
bodyContent = signature;
//all attachments after body
var fullAttachmentContent = string.Empty;
var attachmentBoundary = string.Empty;
attachmentBoundary = boundaryLine NewLine;
attachmentBoundary = "Content-Type: application/{0}; name={1}" NewLine;
attachmentBoundary = "Content-Transfer-Encoding: Base64" NewLine;
attachmentBoundary = "Content-Location: attachment" NewLine;
attachmentBoundary = string.Empty NewLine;
var singleAttachmentContent = string.Empty;
singleAttachmentContent = "{0}" NewLine;
foreach (var attachment in attachments) {
fullAttachmentContent = NewLine.Combine(
string.Format(attachmentBoundary, Path.GetExtension(attachment), Path.GetFileName(attachment)),
string.Format(singleAttachmentContent, Convert.ToBase64String(File.ReadAllBytes(attachment)))
);
}
//final-file
var tmpPath = Path.GetTempPath();
var date = DateTime.Now.ToString("yyyyMMddTHHmmssfff");
var guid = Guid.NewGuid().ToString("N"); //no-hyphens
var fileExtension = ".eml";
var filePath = Path.Combine(tmpPath, "_".Combine(date, guid) fileExtension);
File.WriteAllText(filePath, NewLine.Combine(headerContent, headerBodyBoundary, bodyContent, fullAttachmentContent), Encoding.Default);
var clients = Applications.GetRunningEmailClients();
List<Process> unmanagedProcesses = new List<Process>();
clients.ForEach(c => unmanagedProcesses.AddRange(c.GetProcesses()));
//open file
var managedProcess = Process.Start(filePath);
//this is a workaround for the default behaviour of email clients
//if a client is running when opening an .eml file, then the process of starting the file
//exits immediately and is handed over to the already running client instance
//at this point it's impossible to tell if the file is free to clean up yet
Task.Run(() => {
while (!managedProcess.HasExited) { Thread.Sleep((int)TimeSpan.FromSeconds(60).TotalMilliseconds); }
if (unmanagedProcesses.Any()) unmanagedProcesses.ForEach(Tools.WaitForHasExited);
try {
File.Delete(filePath);
}
catch { /*leave file orphaned*/ }
});
}
}
I don't even know how to define a google search for this problem since I can't avoid using very highly used words like "attachment", "email", "outlook", beside others.
I would appreciate any ideas on how to fix or debug this.
Feel free to ask if any further information is needed.
CodePudding user response:
The paperclip icon visibility in Outlook is determined by the SmartNoAttach
named property (DASL name "http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B"
), the property can be set using MailItem.PropertyAccessor.SetProperty
- set the it using the above DASL name to false.
CodePudding user response:
I've found the problem.
The line:
attachmentBoundary = "Content-Location: attachment" NewLine;
Was suposed to be
attachmentBoundary = "Content-Disposition: attachment" NewLine;
With this change the attachments are shown correctly.