Outlook: Get Image Content ID from existing email

  • Thread starter Thread starter Tora
  • Start date Start date
T

Tora

Hi all,

I have a little big problem. I must clone some email to a new
destination over the cdo.message interface.

I read at this time all properties (from, to, subject, etc) from the
existing email in Outlook 2002 / 2007 via VBA.

We have some emails with embedded images in the email body. When I copy
the attachment and the HTML Body to the new message I get only a red
cross in the body of the new email.

I see in the HTML code that there is a embedded image with the tag 'cid'.

How can I read the Content ID from the existing email and how to write
it to the new email.

I hope someone can help me. I have searched very long in the internet
and I found only examples to create a new mail with a embedded image.

Thanks a lot for help.

Best regards,
Tora
 
If you've looked at those examples of creating an embedded attachment you
then know how to get that PR_ATTACH_CONTENT_ID property from the existing
attachment. You can match that with the text in HTMLBody to see where to set
the cid value. On the new email you'd add that attachment and give it either
the same or a new PR_ATTACH_CONTENT_ID property and make sure the HTMLBody
cid matched.

Of course you'd also need to replicate some other properties such as
PR_ATTACH_MIME_TAG and PR_HIDE_ATTACHMENTS. And to manipulate the attachment
you'd need to save it to the file system so it can be picked up for the new
item.

Also, unless you have Exchange and the admin form has been set to allow CDO
code to access secure properties you will get security warnings as the code
executes or certain property accesses will just fail. CDO security is even
stricter than Outlook object model security.
 
Ken Slovak - [MVP - Outlook] schrieb:

Hi Ken,
If you've looked at those examples of creating an embedded attachment
you then know how to get that PR_ATTACH_CONTENT_ID property from the
existing attachment. You can match that with the text in HTMLBody to see
where to set the cid value. On the new email you'd add that attachment
and give it either the same or a new PR_ATTACH_CONTENT_ID property and
make sure the HTMLBody cid matched.

Of course you'd also need to replicate some other properties such as
PR_ATTACH_MIME_TAG and PR_HIDE_ATTACHMENTS. And to manipulate the
attachment you'd need to save it to the file system so it can be picked
up for the new item.

Also, unless you have Exchange and the admin form has been set to allow
CDO code to access secure properties you will get security warnings as
the code executes or certain property accesses will just fail. CDO
security is even stricter than Outlook object model security.
Thanks for your anwser. I have tried this code example and I have at
the end of the code only a Outlook window with a red cross as image.

I have tried to read the settings and the content id will not write
there. The variable 'ttt2' is empty. I have write the property and after
then I read it again. The id is not written. I don?t why? Can you help
me please?

Sub EmbeddedHTMLGraphicDemo()
' Outlook objects
Dim oApp As Outlook.Application
Dim oMsg As Outlook.MailItem
Dim colAttach As Outlook.Attachments
Dim oAttach As Outlook.Attachment
Dim oPA As Outlook.PropertyAccessor

' not an URL, a DASL property tag string
Const PR_ATTACH_MIME_TAG =
"http://schemas.microsoft.com/mapi/proptag/0x370E001E"

Const PR_ATTACH_CONTENT_ID = "urn:schemas:mailheader:content-id"

' not an URL, a DASL property tag string
Const PR_HIDE_ATTACH =
"http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B"

On Error Resume Next

' create new Outlook MailItem
' Use CreateObject for Outlook.Application if not in OL VBA
Set oApp = Application
Set oMsg = oApp.CreateItem(olMailItem)
' add graphic as attachment to Outlook message
' change path to graphic as needed
Set colAttach = oMsg.Attachments
Set oAttach = colAttach.Add("e:\1.jpg")
oMsg.Save

' *** POSITION CRITICAL *** you must dereference the
' attachment objects before changing their properties
Set colAttach = Nothing
Set oAttach = Nothing

' set properties of the attached graphic that make
' it embedded and give it an ID for use in an <IMG> tag
Set colAttach = oMsg.Attachments
Set oAttach = colAttach.item(1)
Set oPA = oAttach.PropertyAccessor
oPA.SetProperty PR_ATTACH_MIME_TAG, "image/jpeg"
ttt = oPA.GetProperty(PR_ATTACH_MIME_TAG)

oPA.SetProperty PR_ATTACH_CONTENT_ID, "myident"
ttt2 = oPA.GetProperty(PR_ATTACH_CONTENT_ID)

Set oPA = Nothing

Set oPA = oMsg.PropertyAccessor
oPA.SetProperty PR_HIDE_ATTACH, True
ttt3 = oPA.GetProperty(PR_HIDE_ATTACH)

oMsg.Save

oMsg.HtmlBody = "<IMG align=baseline border=0 hspace=0 src=cid:myident>"
oMsg.Close olSave
oMsg.Display

' clean up objects
Set colAttach = Nothing
Set oAttach = Nothing
Set oPA = Nothing
Set oMsg = Nothing
Set oApp = Nothing
End Sub

Best regards,
Tora
 
Does reading those added properties work if you try reading them after
saving the item?




Tora said:
Ken Slovak - [MVP - Outlook] schrieb:

Hi Ken,
If you've looked at those examples of creating an embedded attachment you
then know how to get that PR_ATTACH_CONTENT_ID property from the existing
attachment. You can match that with the text in HTMLBody to see where to
set the cid value. On the new email you'd add that attachment and give it
either the same or a new PR_ATTACH_CONTENT_ID property and make sure the
HTMLBody cid matched.

Of course you'd also need to replicate some other properties such as
PR_ATTACH_MIME_TAG and PR_HIDE_ATTACHMENTS. And to manipulate the
attachment you'd need to save it to the file system so it can be picked
up for the new item.

Also, unless you have Exchange and the admin form has been set to allow
CDO code to access secure properties you will get security warnings as
the code executes or certain property accesses will just fail. CDO
security is even stricter than Outlook object model security.
Thanks for your anwser. I have tried this code example and I have at the
end of the code only a Outlook window with a red cross as image.

I have tried to read the settings and the content id will not write there.
The variable 'ttt2' is empty. I have write the property and after then I
read it again. The id is not written. I don?t why? Can you help me please?

Sub EmbeddedHTMLGraphicDemo()
' Outlook objects
Dim oApp As Outlook.Application
Dim oMsg As Outlook.MailItem
Dim colAttach As Outlook.Attachments
Dim oAttach As Outlook.Attachment
Dim oPA As Outlook.PropertyAccessor

' not an URL, a DASL property tag string
Const PR_ATTACH_MIME_TAG =
"http://schemas.microsoft.com/mapi/proptag/0x370E001E"

Const PR_ATTACH_CONTENT_ID = "urn:schemas:mailheader:content-id"

' not an URL, a DASL property tag string
Const PR_HIDE_ATTACH =
"http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B"

On Error Resume Next

' create new Outlook MailItem
' Use CreateObject for Outlook.Application if not in OL VBA
Set oApp = Application
Set oMsg = oApp.CreateItem(olMailItem)
' add graphic as attachment to Outlook message
' change path to graphic as needed
Set colAttach = oMsg.Attachments
Set oAttach = colAttach.Add("e:\1.jpg")
oMsg.Save

' *** POSITION CRITICAL *** you must dereference the
' attachment objects before changing their properties
Set colAttach = Nothing
Set oAttach = Nothing

' set properties of the attached graphic that make
' it embedded and give it an ID for use in an <IMG> tag
Set colAttach = oMsg.Attachments
Set oAttach = colAttach.item(1)
Set oPA = oAttach.PropertyAccessor
oPA.SetProperty PR_ATTACH_MIME_TAG, "image/jpeg"
ttt = oPA.GetProperty(PR_ATTACH_MIME_TAG)

oPA.SetProperty PR_ATTACH_CONTENT_ID, "myident"
ttt2 = oPA.GetProperty(PR_ATTACH_CONTENT_ID)

Set oPA = Nothing

Set oPA = oMsg.PropertyAccessor
oPA.SetProperty PR_HIDE_ATTACH, True
ttt3 = oPA.GetProperty(PR_HIDE_ATTACH)

oMsg.Save

oMsg.HtmlBody = "<IMG align=baseline border=0 hspace=0 src=cid:myident>"
oMsg.Close olSave
oMsg.Display

' clean up objects
Set colAttach = Nothing
Set oAttach = Nothing
Set oPA = Nothing
Set oMsg = Nothing
Set oApp = Nothing
End Sub

Best regards,
Tora
 
Ken Slovak - [MVP - Outlook] schrieb:

Hi Ken,
Does reading those added properties work if you try reading them after
saving the item?
I have program that the mailitem it will be save after the properties
settings and than I select the attachment item again an read the
properties. The variable ttt2 will be empty again and I dont now why.

I know, this example is not for the cdo interface but I will build that
on a working solution. Can you help me please. Thanks.

Best regards,
Tora


Here the program code:
Sub EmbeddedHTMLGraphicDemo()
' Outlook objects
Dim oApp As Outlook.Application
Dim oMsg As Outlook.MailItem
Dim colAttach As Outlook.Attachments
Dim oAttach As Outlook.Attachment
Dim oPA As Outlook.PropertyAccessor

' not an URL, a DASL property tag string
Const PR_ATTACH_MIME_TAG =
"http://schemas.microsoft.com/mapi/proptag/0x370E001E"

Const PR_ATTACH_CONTENT_ID = "urn:schemas:mailheader:content-id"

' not an URL, a DASL property tag string
Const PR_HIDE_ATTACH =
"http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B"

On Error Resume Next

' create new Outlook MailItem
' Use CreateObject for Outlook.Application if not in OL VBA
Set oApp = Application
Set oMsg = oApp.CreateItem(olMailItem)
' add graphic as attachment to Outlook message
' change path to graphic as needed
Set colAttach = oMsg.Attachments
Set oAttach = colAttach.Add("e:\1.jpg")
oMsg.Save

' *** POSITION CRITICAL *** you must dereference the
' attachment objects before changing their properties
Set colAttach = Nothing
Set oAttach = Nothing

' set properties of the attached graphic that make
' it embedded and give it an ID for use in an <IMG> tag
Set colAttach = oMsg.Attachments
Set oAttach = colAttach.item(1)
Set oPA = oAttach.PropertyAccessor
oPA.SetProperty PR_ATTACH_MIME_TAG, "image/jpeg"

' ***** This property will not be write... I dont know.... ******
oPA.SetProperty PR_ATTACH_CONTENT_ID, "myident"
oMsg.Save

Set colAttach = Nothing
Set oAttach = Nothing

Set colAttach = oMsg.Attachments
Set oAttach = colAttach.item(1)
Set oPA = oAttach.PropertyAccessor

ttt = oPA.GetProperty(PR_ATTACH_MIME_TAG)
ttt2 = oPA.GetProperty(PR_ATTACH_CONTENT_ID)
Set oPA = Nothing

Set oPA = oMsg.PropertyAccessor
oPA.SetProperty PR_HIDE_ATTACH, True
oMsg.Save

ttt3 = oPA.GetProperty(PR_HIDE_ATTACH)

oMsg.HtmlBody = "<IMG align=baseline border=0 hspace=0 src=cid:myident>"
oMsg.Close olSave
oMsg.Display

' clean up objects
Set colAttach = Nothing
Set oAttach = Nothing
Set oPA = Nothing
Set oMsg = Nothing
Set oApp = Nothing
End Sub
 
I don't know where you got that code sample from, but the original was
written using CDO 1.21. The original is at www.outlookcode.com. See
http://www.outlookcode.com/codedetail.aspx?id=27 for one example in CDO,
there are others there as well. You can search there on "embedded" to see
various threads on that.

I would however recommend not using CDO these days unless it's absolutely
necessary. CDO is an optional installation and may not be there. If not it
has to be installed from the Office CD for Outlook 2003 and earlier or it
requires a special download from MS for Outlook 2007. CDO is also subject to
high security, even more so than the Outlook object model guard.




Tora said:
Ken Slovak - [MVP - Outlook] schrieb:

Hi Ken,
Does reading those added properties work if you try reading them after
saving the item?
I have program that the mailitem it will be save after the properties
settings and than I select the attachment item again an read the
properties. The variable ttt2 will be empty again and I dont now why.

I know, this example is not for the cdo interface but I will build that on
a working solution. Can you help me please. Thanks.

Best regards,
Tora


Here the program code:
Sub EmbeddedHTMLGraphicDemo()
' Outlook objects
Dim oApp As Outlook.Application
Dim oMsg As Outlook.MailItem
Dim colAttach As Outlook.Attachments
Dim oAttach As Outlook.Attachment
Dim oPA As Outlook.PropertyAccessor

' not an URL, a DASL property tag string
Const PR_ATTACH_MIME_TAG =
"http://schemas.microsoft.com/mapi/proptag/0x370E001E"

Const PR_ATTACH_CONTENT_ID = "urn:schemas:mailheader:content-id"

' not an URL, a DASL property tag string
Const PR_HIDE_ATTACH =
"http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B"

On Error Resume Next

' create new Outlook MailItem
' Use CreateObject for Outlook.Application if not in OL VBA
Set oApp = Application
Set oMsg = oApp.CreateItem(olMailItem)
' add graphic as attachment to Outlook message
' change path to graphic as needed
Set colAttach = oMsg.Attachments
Set oAttach = colAttach.Add("e:\1.jpg")
oMsg.Save

' *** POSITION CRITICAL *** you must dereference the
' attachment objects before changing their properties
Set colAttach = Nothing
Set oAttach = Nothing

' set properties of the attached graphic that make
' it embedded and give it an ID for use in an <IMG> tag
Set colAttach = oMsg.Attachments
Set oAttach = colAttach.item(1)
Set oPA = oAttach.PropertyAccessor
oPA.SetProperty PR_ATTACH_MIME_TAG, "image/jpeg"

' ***** This property will not be write... I dont know.... ******
oPA.SetProperty PR_ATTACH_CONTENT_ID, "myident"
oMsg.Save

Set colAttach = Nothing
Set oAttach = Nothing

Set colAttach = oMsg.Attachments
Set oAttach = colAttach.item(1)
Set oPA = oAttach.PropertyAccessor

ttt = oPA.GetProperty(PR_ATTACH_MIME_TAG)
ttt2 = oPA.GetProperty(PR_ATTACH_CONTENT_ID)
Set oPA = Nothing

Set oPA = oMsg.PropertyAccessor
oPA.SetProperty PR_HIDE_ATTACH, True
oMsg.Save

ttt3 = oPA.GetProperty(PR_HIDE_ATTACH)

oMsg.HtmlBody = "<IMG align=baseline border=0 hspace=0 src=cid:myident>"
oMsg.Close olSave
oMsg.Display

' clean up objects
Set colAttach = Nothing
Set oAttach = Nothing
Set oPA = Nothing
Set oMsg = Nothing
Set oApp = Nothing
End Sub
 
Ken Slovak - [MVP - Outlook] schrieb:

Hi Ken,
I don't know where you got that code sample from, but the original was
written using CDO 1.21. The original is at www.outlookcode.com. See
http://www.outlookcode.com/codedetail.aspx?id=27 for one example in CDO,
there are others there as well. You can search there on "embedded" to
see various threads on that.

I would however recommend not using CDO these days unless it's
absolutely necessary. CDO is an optional installation and may not be
there. If not it has to be installed from the Office CD for Outlook 2003
and earlier or it requires a special download from MS for Outlook 2007.
CDO is also subject to high security, even more so than the Outlook
object model guard.
I have tried the code (link) but I got an error message in the second
Dim code-line (Dim objMail As MAPI.Message).I have installed the CDO
patch from Microsoft for Outlook 2007 but still get the same error.
I do not know if the CDO interface is the best solution for the problem.
I can tell you what we are trying to do and maybe you have an idea for a
better solution or what else we should try. For a small hint I would be
thankful.

We have an Exchange 2003 server and Outlook 2002/3 on the clients. We
use EventSink to redirect some emails based on the subject line to a
different mailbox. In this mailbox it will be decided if the mail is
allowed to send to the recipient. The email has to be send then with the
original sender to the recipient. If we use the Outlook/Exchange
interface the user who decides about sending or not needs to have the
send-as rights, but that is not what we want, therefore we use the SMTP
relay interface of the Exchange server directly.
The question is: how can we clone and send an email 1:1 but eventually
can alter the from / to / subject line if there is a need for that.

Best regards,
Tora
 
Did you reference CDO in the VBA project, if that's what you're using?

If you're already using the SMTP server directly why not do all that you
want using code to handle things in the SMTP outgoing messages, instead of
using Outlook?

An alternative that I'd probably go with instead would be to set up a
dedicated machine with no Office installed at all on it. Then I'd install
the server side Extended MAPI on that machine, and Redemption. Then I'd use
a special mailbox account that wasn't available to users but only to
Redemption. That mailbox would have the send as permissions and Redemption
could log in and do what it needed to do and then log out or keep running,
whatever.
 
Hi Ken,

i fear my english is not good enough to understand all you were writing:
Did you reference CDO in the VBA project, if that's what you're using?

What do you mean with "did you reference CDO" can you explain it a bit
more? We used CDO for the script, is that what you wanted to know?
If you're already using the SMTP server directly why not do all that you
want using code to handle things in the SMTP outgoing messages, instead
of using Outlook?

We have to to it that way because after the redirection to the mailbox,
a person who has the right to decide if the email is correct and could
be send out or has to be written again with different terms can check
and decide about what to do with the email.

Best Regards,
Tora
 
In the Outlook VBA project select Tools, References. Make sure that MAPI
(CDO.dll) is referenced.
 
Back
Top