Hello there, I've been doing some research about the Outlook.Selection interface and made an application out of it. My goal is to get all of the items in my inbox folder. I have already created a way to get all of them, my problem is to filter each types of items in my inbox. I found a link that could handle it but it is written in VB. It has all of the information that I needed but it seems that I can't get the MessageClass of the variable which is of type Object. Here is the link:

This is exactly what I want my filtering to be in C#. Any thoughts and suggestions I would really appreciate. Thank you.

Dani AI

Generated

A short, practical summary that complements the replies from and and shows the safest ways to detect what kind of Outlook item is selected.

Work flow and rules to follow

  • The Explorer.Selection collection returns generic objects; do not assume a concrete type. Iterate the selection with the Selection.Count/Item(index) pattern (Selection is a collection you must index), and handle each returned object according to its actual type. (learn.microsoft.com)

How to decide item type (three reliable choices)

  • Prefer a strongly-typed test and cast where possible (MailItem, AppointmentItem, MeetingItem, TaskItem, ContactItem). That avoids exceptions and is the simplest Windows/.NET approach.
  • As an alternative, read the MessageClass string (for example: IPM.Note, IPM.Appointment, IPM.Schedule.Meeting.Request, IPM.Contact, IPM.Task, IPM.StickyNote) and branch on that value or its prefix to catch subtypes. The MessageClass property is the canonical way Outlook maps items to forms. (learn.microsoft.com)
  • If you cannot cast (for example, when you only have an object), use a runtime approach (dynamic or reflection) to read the MessageClass property as a fallback instead of assuming the object exposes MailItem members.

Practical cautions (memory and reliability)

  • Avoid two-dot inline COM access (for example doing Application.ActiveExplorer().Selection.Item(...).SomeProp inline) because each dotted access can create extra RCWs. Keep each COM object in a local variable so you can release it deterministically.
  • When automating Outlook from managed code, be deliberate about cleaning up interop references. Calling Marshal.ReleaseComObject is sometimes necessary but must be used carefully; misuse can "poison" shared RCWs. Consult the official guidance and the Visual Studio guidance before forcing releases or GC. (devblogs.microsoft.com)

These notes explain why your original VB pattern (late binding to MessageClass) worked but failed in C#: C# requires either an explicit cast, a runtime-access path (dynamic/reflection), or reading the MessageClass string and switching on it. Use Selection.Count/Item(index), test types first, and use the message-class mapping for any items you do not want to cast. (learn.microsoft.com)

Recommended Answers

All 16 Replies

Accessing mails from outlooks inbox is generally quite simple and mine seems to pick up the differences. What code do you have as while I didnt derrive mine from that vb, mine uses pretty much the same concept.

Thanks for the reply. I'm using VSTO Sir. My only problem right now is to filter the items that I'm dragging (whether it is a MailItem, MeetingItem, AppointmenItem etc.). The sample code in the link uses MessageClass which he got from the variable of type Object which contains the item selected in the ActiveExplorer. I think C# has a different way of getting the MessageClass which is I'm not that really familiar.

Frirstly, Im not male. Please do not make such rash assumptions.

Secondly, Ive asked for some code as it would seem you've approached it very differently from me as all items correctly report their code for me, and perhaps you're going about it the wrong way.

I'm so sorry, I didn't mean it. This is my test program seperated from my application.

private void Form1_Load(object sender, EventArgs e)
 {
  Outlook.Application app = new Outlook.Application();
            Outlook.NameSpace nmspc = app.GetNamespace("mapi");
            Outlook.MAPIFolder inbox = nmspc.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);

          
            Outlook.MeetingItem item;
            for (int i = 8; i < 9; i++)
           {
                item = (Outlook.MeetingItem)inbox.Items[i];
                item.SaveAs(@"c:\TempFile\Temp" + item.EntryID.ToString() + ".msg", Outlook.OlSaveAsType.olMSG);
                MessageBox.Show(item.EntryID.ToString());
            }
           
 }

This is just a test sample because I don't want to mess the whole application that I made. This is my way of getting all the items in my inbox. All I need is a filtering to determine if it is a MailItem, ApplicationItem, MeetingItem etc.

OK, but that will pick up only meeting items, as you cant assign mail items to a meetingitem, it will cause an exception. the messageclass property is text and will confirm then which subtype of the item you picked is, such as out of office etc.

I agree that MessageClass property will confirm which subtype is picked but I'm having a problem how to use it in C#.

Its a string, it will give you in words the type.

PS - just like in the vb example you posted

The line

strMessageClass = oItem.MessageClass

seems does not work in C#. oItem is of type Object. It throws an error.

In your code above, "Outlook.MeetingItem item" as long as you called item.MessageClass you would be ok.

This is what I meant

Outlook.Application app = new Outlook.Application();
Outlook.Selection oSel;
Outlook.Explorer oEx = app.ActiveExplorer;

oSel = oEx.Selection;

Object oItem;

oItem = oSel.Item;

String msgClass = oItem.MessageClass;

I want to know the item selected to filter if it is the item that I want. But it seems the line in red it gives me an error.

Because (DUH) Object is not an outlook class that has that property.

That is what the link exactly did only in VB. I think there is a way in C# but can't just find it.

But VB is lazy and allows you to do hiddeous things like adding characters and integers and setting strings to numbers if you let it. That doesnt make it right.

if you declare object as o you could test if o is Outlook.MailItem that seems to work.

Thanks for the reply, can you show a snippet how to implement?

Good god, no offense but that sounds as lazy as it gets

Outlook.Application app = new Outlook.Application();
Outlook.Selection oSel;
Outlook.Explorer oEx = app.ActiveExplorer;

oSel = oEx.Selection;

Object oItem;

oItem = oSel.Item;
if (oItem is Outlook.MailItem)
{
  Outlook.MailItem oMail = (Outlook.MailItem)Oitem;
  label1.Text = oMail.Subject;
}

all you had to do was paste in the info given..

I now understand, thank you. I'm sorry for letting you post a snippet because I cannot understand well what you mean. Thanks again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.