The new Size property of the Attachment object was introduced in the Outlook 2007 Object Model. There exist at least two methods of getting the attachment size in older Outlook versions, that is in Outlook 2003, XP and 2000.
The first method is as follows: you store each attachment in a temporary file, then query the file size, and after that delete that temporary file. The other, and probably a smarter way, is getting the attachment size via the PR_ATTACH_SIZE Extended MAPI property. It is that second method that we are going to scrutinize today.
The DoGetAttachmentSize method is quite simple, the code below processes the Attachments collection:
Private Sub DoGetAttachmentSize(ByRef mail As Outlook._MailItem)
Dim attachments As Outlook.Attachments = mail.Attachments
If attachments IsNot Nothing Then
Try
If attachments.Count > 0 Then
Dim Output As String = String.Empty
For i As Integer = 1 To attachments.Count
Dim attach As Outlook.Attachment = attachments.Item(i)
If attach IsNot Nothing Then
Try
Dim size As Long = GetMAPIProp( _
attach.MAPIOBJECT, _
MAPI.PR_ATTACH_SIZE)
Output += "#" + i.ToString() + _
": " + attach.FileName + _
" " + size.ToString() + _
Environment.NewLine
Finally
Marshal.ReleaseComObject(attach)
End Try
End If
Next i
If Output <> String.Empty Then MessageBox.Show(Output)
End If
Finally
Marshal.ReleaseComObject(attachments)
End Try
End If
End Sub
In the GetMAPIProp method, you dig for the needed PR_ATTACH_SIZE property. Initialize Extended MAPI, query the right interface, get the SPropValue structure and receive the wanted value. Pay attention here to the two calls of QueryInterface. The point is that Outlook 2003 and Outlook 2007 return only the IMAPIProp interface, while Outlook 2000 and Outlook XP return the IAttach interface only. What kind of interface will be implemented in Outlook 2010 is unclear so far, that is why I am leaving the code as is, with 2 QueryInterface calls:
Private Function GetMAPIProp( _
ByVal oMAPIObject As Object, _
ByVal uiPropertyTag As UInteger) As Long
If (oMAPIObject Is Nothing) Then Return 0
Dim result As String = 0
Dim pPropValue As IntPtr = IntPtr.Zero
Dim IUnk As IntPtr = IntPtr.Zero
Dim IProperty As IntPtr = IntPtr.Zero
Try
MAPI.MAPIInitialize(IntPtr.Zero)
IUnk = Marshal.GetIUnknownForObject(oMAPIObject)
Dim guidMAPIProp As Guid = New Guid(MAPI.IID_IMAPIProp)
Dim res = Marshal.QueryInterface(IUnk, guidMAPIProp, IProperty)
If (res <> MAPI.S_OK) Then
Dim guidMAPIAttach As Guid = New Guid(MAPI.IID_IAttachment)
Marshal.QueryInterface(IUnk, guidMAPIAttach, IProperty)
If (res <> MAPI.S_OK) Then Return 0
End If
Try
MAPI.HrGetOneProp(IProperty, uiPropertyTag, pPropValue)
If (pPropValue = IntPtr.Zero) Then Return 0
Dim propValue As SPropValue
propValue = _
Marshal.PtrToStructure(pPropValue, propValue.GetType())
result = propValue.Value And UInt32.MaxValue
Catch ex As System.Exception
Throw ex
End Try
Finally
If (pPropValue <> IntPtr.Zero) Then
MAPI.MAPIFreeBuffer(pPropValue)
End If
If (IProperty <> IntPtr.Zero) Then
Marshal.Release(IProperty)
End If
If (IUnk <> IntPtr.Zero) Then
Marshal.Release(IUnk)
End If
End Try
Return result
End Function
Have a nice weekend. I hope the weather will finally get better here and I will go fishing to enjoy peace and tranquility, at last!
You may also be interested in:
How to develop an Outlook COM add-in step-by-step
Advanced features for Outlook toolbars, menus and ribbons
Available downloads:
This sample add-in was developed using Add-in Express 2009 for Microsoft Office and .net
C# sample Outlook add-in for VS 2005
VB.NET sample Outlook add-in for VS 2005




