Search code examples
c#emailoutlookoffice-interop

Sending email with image using C# and Outlook Interop vs copy paste image in email


I have made small C# WFP application that sends emails with embedded images using C# and Outlook Interop. It seems that many mail clients reacts diffently to emails sent from this application compared to manually created emails where images are pasted directly in using CTRL+V.

I have tried to use OutlookSpy to compare the two emails, but I can't see any difference that could cause the different way the emails are being handled.

When an email sent from the C# application is received in an Outlook Application on an Iphone, the images are blank. It works just fine when the image is manually created and images are pasted in using CTRL+V.

1) How do I make sure that the emails sent from my application are handled the same way as when I manually create an email in Outlook and copy an image using CTRL+V? If I can make this work, then it should be possible to make the images display correctly in Outlook for Iphone.

2) How does outlook handle an image when it is pasted in using CTRL+V? It seems that it uses Cid, the same way as I do in my application, but how does it refer to the image if it is not attached?

Here is the code for the sample application:

    private void SendEmailButton_OnClick(object sender, RoutedEventArgs e)
    {
        SendMail();
    }

    public void SendMail()
    {
        var application = GetOutlookApplication();
        MailItem newMail = (MailItem)application.CreateItem(OlItemType.olMailItem);
        newMail.To = "!!!EnterValidEmailAddress!!!";
        newMail.Subject = "Image test";

        //Create image as embedded attachment
        Attachment attachment1 = newMail.Attachments.Add(@"C:/SomeImage1.png", OlAttachmentType.olByValue);
        string imageCid1 = "SomeImage_1";

        //The property Accessor to be able to refer to the image from Email HTML Body using CID
        attachment1.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", imageCid1);
        //Set property Accesor to hide attachment
        attachment1.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x7FFE000B", true);

        //Refer the attachment using cid
        newMail.HTMLBody = String.Format("<a href=\"{0}\"><img src=\"cid:{1}\"></a>", "google.dk", imageCid1);
        newMail.Save();
        newMail.Display();
    }

    public static OutlookApplication GetOutlookApplication()
    {
        // Start outlook process if it is not startet already
        if (!IsOutlookRunning())
        {
            using (Process p = new Process())
            {
                p.StartInfo.FileName = "OUTLOOK.EXE";
                p.Start();

                if (!p.WaitForInputIdle(10000))
                    Thread.Sleep(5000);
            }
        }

        // Start the outlook application (API)
        OutlookApplication oApp = null;
        if (Process.GetProcessesByName("OUTLOOK").Any())
        {
            try
            {
                oApp = Marshal.GetActiveObject("Outlook.Application") as OutlookApplication;

            }
            catch (System.Exception)
            {
                if (oApp == null)
                    oApp = new OutlookApplication();
            }
            return oApp;
        }
        oApp = new OutlookApplication();
        return oApp;


    }

    private static bool IsOutlookRunning()
    {
        Process[] p = Process.GetProcessesByName("Outlook");
        return p.Length != 0;
    }

Solution

  • Make sure that you get a well-formed HTML markup finally. The following line of code just adds the <a> tag to the end of body string:

    newMail.HTMLBody += String.Format("<a href=\"{0}\"><img src=\"cid:{1}\"></a>", "google.dk", imageCid1);
    

    Instead, you need to find a right place for the image between the <body> and </body> tags.