2

What I would like to have some assistance with, is determining the type of MailItem loaded into the object using the following snippet of code. You will see I load the object from the active explorer selection and test if it is a mail item. What I would like to avoid picking up are objects like read receipts, meeting acknowledgments, and so forth and to test each type of object I would like to get its type - I attempt to test for that in the else statement below - but all I get in the debug window is "Not a Mail Item: I am a :System.__ComObject".

// set the mail item
object selectedItem = Globals.ThisAddIn.Application.ActiveExplorer().Selection[1];
// This example uses only MailItem. 
if (selectedItem is Outlook.MailItem)
{
 // Cast selectedItem to MailItem. 
 Outlook.MailItem mailItem = selectedItem as Outlook.MailItem;
 // Do something with the MailItem
}
else
{
 // what sort of item are we?
 Debug.WriteLine("I am not a Mail Item: I am a :" + 
 selectedItem.GetType().ToString());
}
fatihyildizhan
  • 8,614
  • 7
  • 64
  • 88
DWE
  • 127
  • 12

2 Answers2

2

The following should do

if(item is MailItem) 
{

}

However, I had to check for 'null' object as well as I was getting a null object for some odd reason. For that reason, I had to use the following, which took care of the problem

if (item != null && item is MailItem)
{
}
TheTechGuy
  • 16,560
  • 16
  • 115
  • 136
1

In general

Com objects don't necessarily have a "class", rather they support interfaces. They only need a "class" if you can create them directly using CoCreateClass, or if you can save them to or load them from a file. This is not the case with many objects, which can only be obtained by getting them from somewhere else.

The way to determine what interfaces they support is to attempt to cast them to that interface type, using IUnknown::QueryInterface. That's what the is keyword is doing.

Objects which can be loaded from and saved to a file will support IPersist::GetClassId to get the clsid of a com object. I believe all the Item types support IPersist, so you can use this method:

In Outlook

In your case you have another option. All the Office Item types support the "Class" property, which returns an enumeration which tells you what type they are. You can invoke this using reflection:

 OlObjectClass = (OlObjectClass)item.GetType().InvokeMember(
     "Class", 
     BindingFlags.GetProperty|BindingFlags.Public, 
     null, 
     item, 
     null);

You can wrap this in a helper function so it isn't as verbose:

public static class OutlookExtensions {
    public OlObjectClass GetOutlookObjectClass(this object item){
          (OlObjectClass)item.GetType().InvokeMember(
     "Class", 
     BindingFlags.GetProperty|BindingFlags.Public, 
     null, 
     item, 
     null);
    }
}
Ben
  • 34,935
  • 6
  • 74
  • 113
  • thanks for the detailed answer ... How would I call the helper function in the example I have referred to ? – DWE Mar 25 '18 at 21:08
  • I provided a + 1 for the great answer ... but I soon found it was rather incomplete, leaving me to find a way to implement the class, which I tried with no success ... I managed to find two links, off the back of your answer, // from https://msdn.microsoft.com/query/dev15.query?appId=Dev15IDEF1&l=EN-US&k=k(Microsoft.Office.Interop.Outlook.OlObjectClass);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.6.1);k(DevLang-csharp)&rd=true and // https://msdn.microsoft.com/en-us/library/office/hh780900(v=office.14).aspx - which combined provided the solution ... – DWE Mar 26 '18 at 11:51