Home > Net >  Emails do not display the paperclip icon even though the attachment is displayed correctly
Emails do not display the paperclip icon even though the attachment is displayed correctly

Time:04-11

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.

Paperclip not showing

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.

  • Related