none
[For Eugene] - Add attachment from stream instead of from file RRS feed

Answers

  • Firstly, olEmbeddeditem means embedded message attachment. For that type, you must pass an Outlook item as the first argument. For a file type attachment (olByValue for the second argument), you can only pass a string with a fully qualified file name. Outlook Object Model does not allow anything else. See https://msdn.microsoft.com/en-us/library/office/ff869553.aspx

    On the Extended MAPI (C++ or Delphi) level, one would need to call IMessage::CreateAttach, then open the PR_ATTACH_DATA_BIN property as IStream (IAttach::OpenProperty(PR_ATTACH_DATA_BIN, IID_IStream, ...)). Once you have a pointer to IStream, you can populate it with data that can come from anywhere. See https://msdn.microsoft.com/en-us/library/office/cc839700.aspx for more details.

    If using Redemption is an option, its RDOMail object (RDOMail.Attachments.Add)  allows to pass a string (file name or url), another Outlook item, IStream or IStorage interface, or a byte array.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    • Marked as answer by Dingoshark Saturday, March 26, 2016 2:32 PM
    Friday, March 25, 2016 11:02 PM

All replies

  • Firstly, olEmbeddeditem means embedded message attachment. For that type, you must pass an Outlook item as the first argument. For a file type attachment (olByValue for the second argument), you can only pass a string with a fully qualified file name. Outlook Object Model does not allow anything else. See https://msdn.microsoft.com/en-us/library/office/ff869553.aspx

    On the Extended MAPI (C++ or Delphi) level, one would need to call IMessage::CreateAttach, then open the PR_ATTACH_DATA_BIN property as IStream (IAttach::OpenProperty(PR_ATTACH_DATA_BIN, IID_IStream, ...)). Once you have a pointer to IStream, you can populate it with data that can come from anywhere. See https://msdn.microsoft.com/en-us/library/office/cc839700.aspx for more details.

    If using Redemption is an option, its RDOMail object (RDOMail.Attachments.Add)  allows to pass a string (file name or url), another Outlook item, IStream or IStorage interface, or a byte array.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    • Marked as answer by Dingoshark Saturday, March 26, 2016 2:32 PM
    Friday, March 25, 2016 11:02 PM
  • Thank you. From first sight, it seems that I need to have the attachment as a file. Let me explain a little more what I am trying to achieve. I am using the Outlook API from managed environment (.NET using NetOffice as wrapper). From inside the ItemSend event I am zipping the attachments to the email, removing the individual attachments from the email, and then adding the new Attachment.zip file as attachment. I have the Attachment.zip in memory and thought it would be possible to add it from within ItemSend as a Stream instead of first saving it to disc and then adding it. 

    Do you agree I need to save Attachment.zip to disc and then add it as an attachment (or can I add it as a stream to avoid the file IO)? 

    I assume the answer is that I need to save it as a file. Then follow-up, do I need to call Save() on the mailItem after the attachment has been added from within the ItemSend? I am not sure if this is required. By testing it seems to work fine without calling Save() after removing the original files and adding the newly created zip file.


    • Edited by Dingoshark Saturday, March 26, 2016 9:52 AM
    Saturday, March 26, 2016 9:05 AM
  • Hello,

    The Outlook object model doesn't provide anything for dealing with streams. You need to use a low-level API on which Outlook is based on - Extended MAPI (or any other third-party wrapper around that API such as Redemption).

    If you prefer going with OOM only - you need to save attachments on the disk, create an archive and then re-attach it to the mail item. Don't forget to remove existing attachments before. Note, there can be embedded images (hidden attachments). You need to keep them for the  HTML markup. So, check the HTMLBody property value and see if any attachments are actually referenced by the img tags. See Distinguish visible and invisible attachments with Outlook VBA for more information and sample code.

    Saturday, March 26, 2016 2:20 PM
  • Yes, you'd need to save the zip file, attach it to the message, delete the zip file, save the message.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Saturday, March 26, 2016 4:18 PM
  • Ok, I will add the extra Save() then at the end even though it is not 100% clear is it is necessary for me yet.
    Saturday, March 26, 2016 4:31 PM
  • It might not be strictly necessary to call Save since Outlook will save the message anyway, but it doesn't hurt either.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Saturday, March 26, 2016 5:07 PM