Add GetAttachmentProperties method
authorThomas
Thu, 07 Mar 2019 10:28:05 +0100
changeset 25958b720212bbdf
parent 2593 c266c7e55440
child 2596 4a8849926eac
Add GetAttachmentProperties method
Mapi.cs
     1.1 --- a/Mapi.cs	Tue Mar 05 11:22:29 2019 +0100
     1.2 +++ b/Mapi.cs	Thu Mar 07 10:28:05 2019 +0100
     1.3 @@ -158,7 +158,7 @@
     1.4              /// <returns>The status of this method.</returns>
     1.5              [return: MarshalAs(UnmanagedType.I4)]
     1.6              [PreserveSig]
     1.7 -            int CreateMessage(IntPtr _interface, uint flags, [MarshalAs(UnmanagedType.Interface)] ref IMessage message);
     1.8 +            int CreateMessage(ref Guid lpiid, uint flags, [MarshalAs(UnmanagedType.Interface)] out IMessage message);
     1.9  
    1.10              /// <summary>
    1.11              /// Copies or moves one or more messages. 
    1.12 @@ -469,7 +469,7 @@
    1.13          /// The IMessage interface defines methods and properties used to manage messages.
    1.14          /// </summary>
    1.15          [ComImport()]
    1.16 -        [Guid("00020307-0000-0000-C000-000000000046")]
    1.17 +        [Guid(Mapi.MAPIInterfaceIds.IMessage)]        
    1.18          [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    1.19          public interface IMessage
    1.20          {
    1.21 @@ -487,7 +487,7 @@
    1.22              int GetNamesFromIDs(out IntPtr lppPropTags, ref Guid lpPropSetGuid, uint ulFlags, out uint lpcPropNames, out IntPtr lpppPropNames);
    1.23              int GetIDsFromNames(uint cPropNames, ref IntPtr lppPropNames, uint ulFlags, out IntPtr lppPropTags);
    1.24              int GetAttachmentTable(uint ulFlags, out IMAPITable lppTable);
    1.25 -            //int OpenAttach(uint ulAttachmentNum, ref Guid lpInterface, uint ulFlags, out IAttach lppAttach);
    1.26 +            int OpenAttach(uint ulAttachmentNum, ref Guid lpInterface, uint ulFlags, out IAttach lppAttach);
    1.27              int CreateAttach();
    1.28              int DeleteAttach();
    1.29              int GetRecipientTable(uint ulFlags, out IMAPITable lppTable);
    1.30 @@ -496,6 +496,12 @@
    1.31              int SetReadFlag(uint ulFlags);
    1.32          }
    1.33  
    1.34 +        [ComImport()]
    1.35 +        [Guid(Mapi.MAPIInterfaceIds.IAttachment)]
    1.36 +        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    1.37 +        public interface IAttach : IMAPIProp
    1.38 +        { }
    1.39 +
    1.40          #endregion
    1.41  
    1.42          #region Structures
    1.43 @@ -692,6 +698,95 @@
    1.44          }
    1.45  
    1.46          /// <summary>
    1.47 +        /// Gets an attachment's properties.
    1.48 +        /// </summary>
    1.49 +        /// <param name="omi">The Outlook mail item that contains the attachment.</param>
    1.50 +        /// <param name="index">The attachment's index. 0-based.</param>
    1.51 +        /// <param name="mapiProperties">The MAPI properties to get its values for.</param>
    1.52 +        /// <param name="propertyValues">The property values that have been returned.</param>
    1.53 +        /// <returns>The status (Mapi.HResult) of this method.</returns>
    1.54 +        public static int GetAttachmentProperties(Outlook.MailItem omi,
    1.55 +                                                  int index,
    1.56 +                                                  List<MapiProperty.MapiProp> mapiProperties,
    1.57 +                                                  out MAPIProperties propertyValues)
    1.58 +        {
    1.59 +            int result = (int)Mapi.HResult.S_FALSE;
    1.60 +            propertyValues = null;
    1.61 +
    1.62 +            try
    1.63 +            {
    1.64 +                // Get the IMessage interface
    1.65 +                IMessage iMessage = (IMessage)omi?.MAPIOBJECT;
    1.66 +                if (iMessage == null)
    1.67 +                {
    1.68 +                    throw new Exception("Could not get IMessage interface.");
    1.69 +                }
    1.70 +
    1.71 +                // Open the attachment
    1.72 +                Guid guid = (typeof(Mapi.IAttach)).GUID;
    1.73 +                result = iMessage.OpenAttach((uint)index, ref guid, 0, out IAttach attachment);
    1.74 +
    1.75 +                // If we can't open the attachment, throw error
    1.76 +                if (result != 0)
    1.77 +                {
    1.78 +                    throw new Exception("Error opening attachment. " + Mapi.GetHResultError(result));
    1.79 +                }
    1.80 +
    1.81 +                // Create the SPropValue structure
    1.82 +                Mapi.SPropValue sPropValue = new Mapi.SPropValue();
    1.83 +                int propValueSize = Marshal.SizeOf(sPropValue);
    1.84 +
    1.85 +                // Allocate memory for the array of SPropValues to set
    1.86 +                int propertiesCount = mapiProperties.Count;
    1.87 +                IntPtr propTagArray = Marshal.AllocHGlobal(propValueSize * propertiesCount);
    1.88 +
    1.89 +                // Create the property values array
    1.90 +                uint[] propertyTags = new uint[propertiesCount + 1];
    1.91 +                propertyTags[0] = (uint)propertiesCount;
    1.92 +                for (int i = 0; i < propertiesCount; i++)
    1.93 +                {
    1.94 +                    propertyTags[i + 1] = (uint)mapiProperties[i].Tag;
    1.95 +                }
    1.96 +
    1.97 +                // Get properties
    1.98 +                result = attachment.GetProps(propertyTags, Mapi.MAPI_UNICODE, out uint valuesCount, out IntPtr propArray);
    1.99 +
   1.100 +                // If an error occured, just log at this point.
   1.101 +                if (result != 0)
   1.102 +                {
   1.103 +                    Log.Error("OpenAttachment: Error getting attachment properties. " + Mapi.GetHResultError(result));
   1.104 +                }
   1.105 +
   1.106 +                // Convert the retrieved values
   1.107 +                object[] values = new object[valuesCount];
   1.108 +                for (int i = 0; i < valuesCount; i++)
   1.109 +                {
   1.110 +                    sPropValue = (SPropValue)Marshal.PtrToStructure((propArray + (i * propValueSize)), typeof(SPropValue));
   1.111 +                    values[i] = Mapi.ConvertSPropValueToObject(mapiProperties[i], sPropValue);
   1.112 +                }
   1.113 +
   1.114 +                // Check if returned values match properties count
   1.115 +                if (propertiesCount != valuesCount)
   1.116 +                {
   1.117 +                    throw new Exception("Properties count doesn't match values count.");
   1.118 +                }
   1.119 +
   1.120 +                // Create return dictionary
   1.121 +                propertyValues = new MAPIProperties();
   1.122 +                for (int i = 0; i < valuesCount; i++)
   1.123 +                {
   1.124 +                    propertyValues.Add(mapiProperties[i], values[i]);
   1.125 +                }
   1.126 +            }
   1.127 +            catch (Exception ex)
   1.128 +            {
   1.129 +                Log.Error("OpenAttachment: Error getting attachment.  " + ex.ToString());
   1.130 +            }
   1.131 +
   1.132 +            return result;
   1.133 +        }
   1.134 +
   1.135 +        /// <summary>
   1.136          /// Gets the attachment table of an Outlook mail item.
   1.137          /// </summary>
   1.138          /// <param name="omi">The Outlook mail item to get its attachment table for.</param>