Thursday, March 22, 2007

I removed my FeedMap

So, I removed my FeedMap. I really didn't intend to, but since it was possible to submit a blog using an adress but not possible to update the location without adding a Geo-tag to the rss (which is generated by BlogSpot of course) I really had no choice.

Sucks to have one strategy for submittin a new blog and another for updating. Thats minus -100 User Experience points for FeedMap! Shame on you.

CDO and MAPI vs. C#

In a wild side-project I have started investigating how to extract appointment information from an Exchange server. To be honest this work is more like archeology (often resulting in dead links to some long forgotten Microsoft or MSDN page) than any other form of... -logy.

After having looked at the MAPI implementation on the Windows side (mapi32.dll) I found myself reeeeally reluctant to do Interop against this .dll. Any documentation and/or samples are at best provided for C++ (not really a problem, just boring after having idled around in managed programming the last few years) and MCF (now this is a problem).

At first I glanced at the Mapi33 wrapper around Mapi32.dll, the price tag however quickly persuaded me to start looking in another direction. $1000 might seem like a lot of money for a wrapper around one single dll, but I'm sure the guy deserves it, personally I'm not that into this side-project yet.

Turns out I don't need that. The CDO (Collaboration Data Objects) provides a wrapper around the MAPI interface and exposes a lot of the objects. A simple interop to CDO.dll I can live with.

Only problem now is that we are back in Interop/COM-hell. At first I used the as operator in C# to cast stuff to the right type (since all types are object when you interop). What I did forget was that a new instance is created every time. This did take some while to set straight.

So, what I did at first was:

// Create session and logon
MAPI.Session session = new MAPI.Session();
session.Logon(name, password, true, true, this.Handle.ToInt64(), false,
String.Format("{0}\n{1}", server, mailbox));

// Get the folder
MAPI.Folder inboxFolder = session.Inbox as MAPI.Folder;

// Enumerate messages
MAPI.Message message = (MAPI.Message)(inboxFolder.Messages as MAPI.Messages).GetFirst(null);
while (message != null)
{
// do stuff with the message
message = (MAPI.Message)(inboxFolder.Messages as MAPI.Messages).GetNext();
}

Do yo see whats wrong here? Cause I didn't at first. Hint, as I said above, a new object is created every time you call get on a property. So, the MAPI.Messages object I get in the GetFirst-line, is not the same as I get in the GetNext-line. In this case it makes no difference, but when we start playing around with the Messagefilter we have a problem. The GetFirst-call creates a forward only pointer in the messages object that is then used by the GetNext-call. By calling the inboxFolder.Messages for every step, we get an infinite loop here (since every call to messages creates a new instance of and that new instance has a pointer that points to the first message in the list)....

The code above should be:

// Create session and logon
MAPI.Session session = new MAPI.Session();
session.Logon(name, password, true, true, this.Handle.ToInt64(), false,
String.Format("{0}\n{1}", server, mailbox));

// Get the folder
MAPI.Folder inboxFolder = session.Inbox as MAPI.Folder;

// Enumerate messages
MAPI.Messages messages = (MAPI.Messages)inboxFolder.Messages;
message = (MAPI.Message)messages.GetFirst(null);
while (message != null)
{
// do stuff with the message
message = (MAPI.Message)messages.GetNext();
}

A subtle but important difference that is.

So, the moral of the story is:

  • You get lazy after having played around in Managed space for too long.
  • I still don't like COM.

Hooked on Heroes

After having watched more than 10 episodes in less than a week I think it is time to be honest about it. I'm hooked on the tv-series Heroes. Good thing is that I have two accomplices (not named here, but you know who you are Stoffe and Tove).


Anyway, it's actually really good and I do recommend it...