Drag and Drop Outlook Appointments

Hi there.

I would like to be able to drag and drop emails and calendar entries from Outlook into my .NET windows forms applications, and whilst I have this working for messages, I am struggling with Outlook calendar entries.

I have implemented the Aspose.Email.Windows.Forms.FileDropTargetManager class and have successfully loaded dropped emails messages into an object using the Aspose.Email.MailMessage.Load() method.

To do this I first save the dropped mail message to file before calling the load method:

Dim output As System.IO.FileStream
output = New System.IO.FileStream(strFilename, System.IO.FileMode.CreateNew)
args.Files(i).Save(output)
output.Close()

Dim objOutlookItem As Aspose.Email.MailMessage = Aspose.Email.MailMessage.Load(strFilename)

Whilst this also works with dropped Outlook calendar entries, the resultant MailMessage object doesn’t provide properties to access calendar entry information like location and attendees. If I save the MailMessage object to file after dragging a calendar entry into the application, it does however save all the outlook meeting information.

I looked at using the Aspose.Email.Calendar.Appointment.Load() method when dragging in Outlook calendar entries, but this always fails with the error:

“A first chance exception of type ‘Aspose.Email.AsposeInvalidDataException’ occurred in Aspose.Email.dll. Additional information: The data appears to be corrupted.”

So my question is, when dragging items from Outlook onto a FileDropTargetManager, how do I determine which dropped files are emails and which are meetings, and then how do I load the meetings into an object that allows me to interrogate the Outlook Meeting properties (i.e. location, attendees, start time, end time etc).

Hopefully that makes sense.

Any help is welcome.

Thanks.

@anthony.clewlow

Thank you for contacting Aspose Support.

You may use MapiMessage class instead of MailMessage. This class provides various methods to load MSG like as FromFile, FromMailMessage and Load. Once the MSG is loaded into MapiMessage object, you may use MessageClass property to get such information that it is a meeting or simple mail. This property specifies the type, purpose, or content of the message. If the MSG is a plain email then MessageClass shall return IPM.Note and in case of appointment, this property shall return IPM.Appointment etc.

This can be used as follows:

Dim objOutlookItem As Aspose.Email.Mapi.MapiMessage = Aspose.Email.Mapi.MapiMessage.FromFile(strFilename)
MessageBox.Show(objOutlookItem.MessageClass)

Moreover, we hope that this shall resolve your problem. Please feel free to write back to us if you need additional information or you have any further queries.

That’s great thanks.

I almost have this working, with just a couple more queries:

1.) When examining the MapiMessage objects in Visual Studio, I am able to drill down and see set property values. I was specifically looking for how the appointment location would be stored. I can see it is stored with property ID 2148204575, but this appears not to be Aspose.Email.Mapi.MapiPropertyTag.PR_LOCATION which has the ID 973930526 (this tag has no value set). To make the code more readable, how to I find out which PR_ tag has the ID 2148204575?

I have identified a few other properties this way but would rather use the more descriptive MapiPropertyTag in the code.

2.) Finally, I haven’t been able to find out which appointment recipients have been flagged as required attendees. I loop through the recipients like this but I cannot seem to find a RequiredAttendee flag (or something similar) for each recipient.

For Each aRecipient As Aspose.Email.Mapi.MapiRecipient In objMapiMessage.Recipients
Next

Is there another way to do this?

Many thanks in advance.

@anthony.clewlow

Thank you for writing back to us.

We have logged your queries with IDs “EMAILNET-39249” and “EMAILNET-39250” for further investigation. You will automatically be informed here once we have more information to share.

@anthony.clewlow

The MapiPropertyTag.PR_LOCATION property specifies the location of the contact as described
here: ([MS-OXOCNTC]: PidTagLocation Property | Microsoft Learn).

The property that contains appointment location is a named property and does not have a persistent id as described here: ([MS-OXOCAL]: PidLidLocation Property | Microsoft Learn).

You may find it by descriptor:

MapiMessage msg = MapiMessage.FromFile(@"E:\test appointment.msg");

foreach (var msgNamedProperty in msg.NamedProperties.Values)
{
 if (msgNamedProperty.Descriptor == KnownPropertyList.Location)
 {
  // The appointment location property is here
  string location = msgNamedProperty.GetString();
 }
} 

Furthermore, please feel free to write back to us if you need additional information.

@anthony.clewlow

Regarding RequiredAttendee flag, there is no special property for RequiredAttendee at the MAPI level but you can use RecipientType for this purpose because To / CC / BCC recipients are mapped as Required / Optional / Resource for meetings as shown below:

    MapiMessage message = MapiMessage.FromFile(filename);
    string role = string.Empty;
    foreach (MapiRecipient item in message.Recipients)
    {
        switch (item.RecipientType)
        {
            case MapiRecipientType.MAPI_TO:
                role = "REQ-PARTICIPANT";
                break;
            case MapiRecipientType.MAPI_CC:
                role = "OPT-PARTICIPANT";
                break;
            case MapiRecipientType.MAPI_BCC:
                role = "NON-PARTICIPANT";
                break;
        }
    } 

Moreover, please share your feedback and feel free to write back to us if additional information is required.

Great response.

I’ll try out both suggestions now.

OK I have tested both methods and I have this all working. Thanks for the help.

Once more query…

When dragging in a re-occurring appointment, I can inspect the named properties of the MapiMessage object, but I cannot see any property that gives me the start and end date/time of the specific appointment instance I have dragged from Outlook. The usual start and end date properties give the start and end date of the 1st Appointment in the re-occurring schedule, not the appointment I dragged.

I hope that makes sense, and would appreciate any help with this.

Thanks in advance.

@anthony.clewlow

It is requested to kindly share the code sample with us so that we could investigate in detail.