locked
C#: add a resource as an attachment to an Outlook mail item RRS feed

  • Question

  • Hello there,

    I've posted almost the same question on stack overflow, but it doesn't get a lot of view, so here I am!

    I've got a WPF application. This application displays information to a user. I want the user to be able to send an email of the current information with a button (via a command). The important thing: the email will contain embedded images.

    To do this:

    • the button is binded to a command;
    • the command executes a method;
    • in this method, the information is formatted as HTML with a .tt file; in this file, the images are referenced via their cid, like this:
    <img src="cid:myImageCid" alt="an image" />

    I started to put my images in an Assets folder in my projet. That way, I could easily create an attachment this way:

    using OutlookApp = Microsoft.Office.Interop.Outlook.Application;
    [...]
    namespace MyApp
    {
        public class MyClass
        {
            private void SendMail()
            {
                OutlookApp outlookApp = new OutlookApp();
                MailItem mailItem = outlookApp.CreateItem(OlItemType.olMailItem);
                [...]
                var rootDirectory = System.Windows.Forms.Application.StartupPath;
                Attachment myAttachment = mailItem.Attachments.Add(Path.Combine(rootDirectory, @"../../Assets/image.png"));
                myAttachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", "myImageCid");
                [...]
                mailItem.Display(false);
            }
        }
    }

    You can see what's wrong here: when I build my project, the Assets folder is not exported, and if I copy the generated exe and its dependencies somewhere else, the application crashes because the file is not found.

    So, I integrated my images in the resources of the project (Resources.resx). That way, I can simply access my image this way:

    Properties.Resources.image;

    Problem: apparently it's not possible to do the following:

    using OutlookApp = Microsoft.Office.Interop.Outlook.Application;
    [...]
    namespace MyApp
    {
        public class MyClass
        {
            private void SendMail()
            {
                OutlookApp outlookApp = new OutlookApp();
                MailItem mailItem = outlookApp.CreateItem(OlItemType.olMailItem);
                [...]
                var rootDirectory = System.Windows.Forms.Application.StartupPath;
                Attachment myAttachment = mailItem.Attachments.Add(Properties.Resources.image);
                myAttachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", "myImageCid");
                [...]
                mailItem.Display(false);
            }
        }
    }

    Because Attachments.Add takes either a file name as first parameter or an Outlook attachment (that I can't create; I can only get it from an existing email).

    So... What are my options from here? Do I need to create a temporary file from the resource, and then take its full path to pass it as parameter? Another option would be to create a folder to export when I build my app. That way I could refer to the file in that folder. Is that possible? Or, I am doing things totally wrong to achieve my goal...

    To be honest it'll be my first "true" WPF app that is a little "rich", so it's the first time that I need a resource.

    Thanks!


    • Edited by béni Saturday, October 21, 2017 1:58 PM
    Saturday, October 21, 2017 1:55 PM

Answers

  • OK, in the end I adapted my method. In the build action for all the images that I needed, I did the following (this is available in the property tab for the file):

    • Build action: Content.
    • Copy to output directory: Copy if newer.

    build options

    That way, at build, the folder containing my images (and my images) are copied to the build directory. I can then use their relative URL:

    Attachment myAttachment = mailItem.Attachments.Add(Path.GetFullPath("Assets/image.png"));
    I don't know if it's the only way to do it, but it works, it doesn't seem ugly and I can still use the images in the XAML. When images are placed in a resx file, apparently, it's a PITA.

    • Marked as answer by béni Sunday, October 22, 2017 2:27 PM
    Sunday, October 22, 2017 2:26 PM

All replies

  • OK, in the end I adapted my method. In the build action for all the images that I needed, I did the following (this is available in the property tab for the file):

    • Build action: Content.
    • Copy to output directory: Copy if newer.

    build options

    That way, at build, the folder containing my images (and my images) are copied to the build directory. I can then use their relative URL:

    Attachment myAttachment = mailItem.Attachments.Add(Path.GetFullPath("Assets/image.png"));
    I don't know if it's the only way to do it, but it works, it doesn't seem ugly and I can still use the images in the XAML. When images are placed in a resx file, apparently, it's a PITA.

    • Marked as answer by béni Sunday, October 22, 2017 2:27 PM
    Sunday, October 22, 2017 2:26 PM
  • see this link:

    Send Email with Attachment in C#

    https://www.e-iceblue.com/Tutorials/Spire.Email/Spire.Email-Program-Guide/Send-Email-with-Attachment-in-C-VB.NET.html

    Monday, October 30, 2017 6:31 AM