Is it possible to get attachment content - Outlook Add-in API - outlook-addin

Is it possible to get attachment content(eml file) in Outlook Add-in API?. If yes, please guide how to do it.

Call Attachment.SaveAsFile to save the attachment.
If you are trying to access the attachment contents without saving the attachment as a file, Outlook Object Model won't help you. You can use either Extended MAPI (C++ or Delphi only) and open the attachment data as a stream (IAttach::OpenProperty(PR_ATTACH_DATA_BIN, IID_IStream, ...)) or use Redemption (I am its author) - its attachment objects expose AsText, AsArray, etc properties.
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set item = Session.GetMessageFromID(Application.ActiveExplorer.Selection(1).EntryID)
for each attach in item.Attachments
MsgBox attach.AsText
next

There is an example on how to do this here:
Using:
var attachmentData =
attachment.PropertyAccessor.GetProperty(
PR_ATTACH_DATA_BIN);
But when I tried to do this I just got an exception.

Related

Reply, with template, using properties of original mail

I work at a Company that gets requests we filter in terms of
being eligibile for financing from our financing partner
requiring more information from the enquirer
There is a lot of monotonous work, in copy pasting email replies.
I looked into creating a Quick Action in Outlook, but because our mother company does not allow certain freedoms, like the Font has to be specifically Segoe Ui Light etc. I could not use this, so I thought about writing a macro.
I intended for a macro button to:
Open a new Reply email, replying to all in the original mail.
In this new email text body, use a template email that I already made and saved as a template. (This way it saved the Font, size and other formatting.)
Put in the original Sender and CC'ed mail addresses as well as the Subject from the original mail.
And then display the email, so I could make edits if I wanted to before sending.
Sub ReplyGewerbeanmeldung()
Dim origEmail As MailItem
Dim replyEmail As MailItem
Set origEmail = Application.ActiveWindow.Selection.Item(1)
Set replyEmail = Application.CreateItemFromTemplate(" "C:\Users\XYZ\AppData\Roaming\Microsoft\Templates\ReplyGewerbeanmeldung.oft"\ReplyGewerbeanmeldung.oft")
replyEmail.To = origEmail.Sender
replyEmail.CC = origEmail.CC
replyEmail.Subject = origEmail.Subject
replyEmail.HTMLBody = replyEmail.HTMLBody & origEmail.Reply.HTMLBody
replyEmail.Display
End Sub
First of all, it seems you need to correct the file path to the template message. The following string is not a valid file path:
" "C:\Users\XYZ\AppData\Roaming\Microsoft\Templates\ReplyGewerbeanmeldung.oft"\ReplyGewerbeanmeldung.oft"
Try to use the following string instead:
Set replyEmail = Application.CreateItemFromTemplate("C:\Users\XYZ\AppData\Roaming\Microsoft\Templates\ReplyGewerbeanmeldung.oft")
You can read more about that in the How To: Create a new Outlook message based on a template article.
Anyway, creating items from a template will not preserve the original message body. Moreover, in Outlook you will not get any visual appearance that a particular items was replied. So, you need to call the ReplyAll method on the original item in Outlook to avoid this artefacts in Outlook.
You can create a new mail item, but only for copying the message body response which is required to paste into the reply. The NameSpace.OpenSharedItem method can be used to to open iCalendar appointment (.ics) files, vCard (.vcf) files, and Outlook message (.msg) files. You may consider using it instead of creating a new item based on the template to grab the message body from there.

How to bulk export Attachments from emails (which are emails) to another folder within Outlook

I need to extract .msg attachments from emails in a range and save these into another outlook sub-folder. This works currently by dragging the attachment into a sub-folder of 'inbox' but is there a quicker way?
I have searched around a bit and found ways to extract them to a local folder but i need them to be contained within outlook.
I appreciate any help and suggestions.
Thanks.
There are two problems here - first is accessing embedded message attachments without saving them first as MSG file. Second is importing the MSG files back - you can use Application.CreateItemFromTemplate, but the item will be unsent. You can use Namespace.OpenSharedItem, and then use MailItem.Move, but it is still a kludge.
There issn't much much you can do in OOM alone. Extended MAPI would work, but it is C++ or Delphi only. If using Redemption is an option (I am its author), you can use EmbeddeedMsg property exposed by the Redemption RDOAttachment object. You can also use RDOMail.CopyTo and pass a folder as a parameter to copy an embedded message attachment to a folder:
Set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set redItem = Session.GetMessageFromId(OutlookMessage.EntryID)
set redFolder = Session.GetFolderFromId(OutlookFolder.EntryID)
for each attach in redItem.Attachments
if attach.Type = olEmbeddeditem Then
attach.EmbeddedMsg.CopyTo OutlookFolder
End If
next

VBA Outlook code to open Mail Item and Save As text

I'm receiving Outlook mails that have other Outlook mails (*.msg) as attachments. I need them in txt format (or anything else Word can open).
I seem to have two choices:
1) Save the attachments to my drive as text files, rather than msg files. I have no idea how to do that, either manually or by code.
2) Save the attachments as msg files (I got a macro here on SO that does that), then open each file and save it at txt. But File-->Open in Outlook 2010 has no option for opening msg files. The only way I can see to open the file is to (manually) view the folder in File Explorer and double-click it. Once its open, I can use File-->SaveAs.
3) I could open and save the file in VBA. Or can I? (It seems you can't record a macro in Outlook the way you can in Word or Excel, or I would have tried it.)
EDIT: I tried Dmitri's suggestion, and this seems to work:
Dim oNamespace As NameSpace
Dim oFolder As Folder
' Get a reference to a NameSpace object.
Set oNamespace = Application.GetNamespace("MAPI")
' Open the file containing the shared item.
Set oSharedItem = oNamespace.OpenSharedItem("D:\temp.msg")
' Save the item to the folder.
oSharedItem.SaveAs "D:\temp.txt"
Save the embedded message attachments as MSG files (Attachment.SaveAsFile), then open then using Namespace.OpenSharedItem.
If you want to access the embedded message attachments as messages without saving them, you'd need either Extended MAPI (IAttach::OpenProperty(PR_ATTACH_DATA_OBJ, IID_IMessage, ...), C++ or Delphi only) or Redemption (I am its author - it exposes Attachment.EmbeddedMsg property).

How to test FileName property of Outlook attachment

Some Outlook VBA code that saves email attachments according to their file names failed on an embedded bitmap image when it tried to access the FileName property of that "attachment."
How can I detect this? The FileName property is supposed to be a String but neither of these tests catches it:
If objAtt.FileName = "" Then ....
If objAtt.FileName = vbNullString Then ....
But every attempt to access this property throws a run-time error:
Outlook cannot perform this action on this type of attachment.
I would prefer not to use the DisplayName property if possible.
Also, it seems that I could filter the attachments according to the value of their FileType properties but I have not been able to find a list associating these Integer values with file types.
Advice is appreciated.
FileName property is only applicable to the regular olByValue type attachments. In your case you are most likely dealing with an olOLE type attachment, which is really a serialized embedded OLE object - the stream stores the bitmap (or metafile) that Outlook uses to represent the image as well as the actual data that the original application that created the data (MSPaint?) can use to edit it.
OLE attachment data is stored in the IStorage interface format. The actual format of the data depends on the application used to create it (MSPaint, Excel, etc.). Outlook Object Model does not let you save such attachments using Attachment.SaveAsFile.
Depending on the language you are using (C++ or Delphi would be best), you will need to open the PR_ATTACH_DATA_OBJ property as IStorage and then extract the data (IAttach::OpenProperty(PR_ATTACH_DATA_OBJ, IID_IStorage, ...)) . Take a look at the message with OutlookSpy (I am its author) - click IMessage button, go to the GetAttachmentTable tab, double click on the OLE attachment, select the PR_ATTACH_DATA_OBJ, right click, IMAPIProp::OpenProperty.
If using Redemption is an option (I am also its author), it extracts the the attachment data for a dozen or so most popular formats (MSPaint, Excel, Word, PDF, etc.):
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set OutlookMsg = Application.ActiveExplorer.Selection.Item(1)
set Msg = Session.GetRDOObjectFromOUtlookObject(OutlookMsg)
for each attach in Msg.Attachments
attach.SaveAsFile "c:\temp\" & attach.FileName
next

Moving an attachment from an email into an Outlook folder

I'm trying to take attachments from mails received and move them into a folder within Outlook.
I can move the entire message, and I've also worked out how to save the attachments to a drive, but neither of these things is what I'm looking for.
I was looking at something along the lines of the below, but I'm guessing there is no Attachment.Move similar to MailItem.Move.
Sub test1()
Dim olFolder As MAPIFolder
Set olFolder = Application.GetNamespace("MAPI").Folders("Mailbox - Test").Folders("Inbox")
Dim Item As Object
For Each Item In olFolder.Items
Set oMail = Item
For Each att In oMail.Attachments
att.Move Application.GetNamespace("MAPI").Folders("Enterprise Connect").Folders("Test")
Next
Next
End Sub
The attachments do not exist as standalone entities in folders - what you see if a message with a single attachment. The item's message class is IPM.Document.* - when you double click on an item like that, Outlook is smart enough to open the attachment instead of showing an inspector. Take a look at such an item with OutlookSpy (I am its author - click IMessage and Item buttons).
Outlook Object Model does not allow to create DocumentItem objects directly. But you can create a regular MailItem object, add an attachment using MailItem.Attachments.Add, then reset the MessageClass property appropriately - e.g. for a ".txt" attachment, look up HKEY_CLASSES_ROOT\.txt registry key, read the default value, append it to message class (IPM.Note.txtfile).
If using Redemption (I am also its author) is an option, it exposes the RDODocumentItem and allows to create document items directly (see the examples).
The Attachment class doesn't provide such methods. You need to save the attached file to the disk and then re-attach it anew to another Outlook item.
You may find the Getting Started with VBA in Outlook 2010 article helpful.