GetContactPictureAttachment, SetContactPicture and Exchange 2007


The EWS methods GetContactPictureAttachment and SetContactPicture are not available in Exchange 2007, so how do you programmatically access a contact’s picture?

Fortunately, Exchange 2007 still supports CDO.  While is it de-emphasized, this simply means that while it is recommended to use EWS where possible, sometimes it may not be and so CDO is available for these situations.

This question came up recently, so I have two CDO scripts.  One will extract the contact picture to a file, and the other will update it from a file.  Now, CDO is also not supported from managed code, so implementation can be tricky (if being supported is important).  The way I implemented my example in a .Net program was to implement the CDO part as vbs script files.  These can be spawned by the .Net program as needed.  The full example actually checks the version of Exchange, and if possible will use the native EWS methods.  If these aren’t available, the CDO scripts are spawned as needed to extract or update contact pictures.

So, on to the code.  To extract a contact picture, the following CDO will work (you need to provide the server name, mailbox name, contact EntryID, and target filename).

mapiserver = "%SERVER%"
mapimailbox = "%MAILBOX%"
contactEntryID = "%CONTACTENTRYID%"
filename = "%IMAGEFILE%"


set objSession = CreateObject("MAPI.Session")
Const Cdoprop1 = &H7FFF000B
Const Cdoprop2 = &H370B0003
strProfile = mapiserver & vbLf & mapimailbox
objSession.Logon "", "", False, True, 0, False, strProfile
Set objInbox = objSession.Inbox
Set objInfoStore = objSession.GetInfoStore(objSession.Inbox.StoreID)
set objmessage = objSession.getmessage(contactEntryID)
for each objAttachment in objMessage.Attachments
	if objAttachment.fields(CdoProp1).Value=true then
		' This is our contact picture
		objAttachment.WriteToFile(filename)
        exit for
	end if
next
 

In my test application I populated the variable values automatically before spawning the script, and the contact picture would end up as a temporary file that could then be shown and deleted.

 

To update the contact picture (the same variables are needed, but a source image file instead of a target file), the following does the job.  Note that the script needs the source file to be named ContactPicture.jpg, or it will fail.  Again, once the script is finished, the source file can be deleted.

 

mapiserver = "%SERVER%"
mapimailbox = "%MAILBOX%"
contactEntryID = "%CONTACTENTRYID%"
filename = "%IMAGEFILE%"


set objSession = CreateObject("MAPI.Session")
Const Cdoprop1 = &H7FFF000B
Const Cdoprop2 = &H370B0003
strProfile = mapiserver & vbLf & mapimailbox
objSession.Logon "", "", False, True, 0, False, strProfile
Set objInbox = objSession.Inbox
Set objInfoStore = objSession.GetInfoStore(objSession.Inbox.StoreID)
set objmessage = objSession.getmessage(contactEntryID)

' Delete the current contact picture
on error resume next
for each objAttachment in objMessage.Attachments
	if objAttachment.fields(CdoProp1).Value=true then
		if err.number=0 then
			' This is the current contact picture, so delete it
			objAttachment.Delete()
			exit for
		else
			err.clear
		end if
	end if
next

' Add new contact picture
set oAttach=objMessage.Attachments.Add
with oAttach
	.Position=-1
	.Type=1
	.Source=filename
	.ReadFromFile filename
end with

for each objAttachment in objMessage.Attachments
	if objAttachment.Name="ContactPicture.jpg" then
		objAttachment.fields.add Cdoprop1, "True"
		objAttachment.fields(Cdoprop2).value=-1
		exit for
	end if
next
objMessage.fields.add "0x8015", 11, "True", "0420060000000000C000000000000046"
objMessage.Update
Comments (0)

Skip to main content