Saturday, April 29, 2006

Bug in Microsoft CDO For Windows 2000 Library?

I came across this while writing some code using the Outlook Object Model and CDO For Windows 2000. My requirement is simple. Convert each Outlook MailItem in the Inbox folder to CDO Message object which is processed further. The algorithm that i use is :

msgs(i) = new cdo message
msgs(i).from = mailitem.from
msgs(i).subject = mailitem.subject
copy all the corresponding fields form outlook mailitem to cdo message object

for each attachment in mailitem
tmpname = tmp + "\" +
mailitem.saveAttachment in tmpname
msgs(i).addAttachment tmpname
delete the file tmpname
delete the tmp folder

What i am doing is very simple, copy all Outlook MailItem fields to corresponding CDO Message object fields. Then for each attachment in the MailItem, save the attachment in some temporary directory (tmp) with the name same as the attachment name. Then add that file as an attachment to the CDO Message object. Delete the temporaryt file. Once all the messages are converted, delete the temporary folder.

Problem occurs when an attempt is made to delete the temporary file, i.e when i am deleteing the temporary file in the loop. The error was straight forward, file access error, cannot delete the file. Which meant that there is some reference, even after the file is added as attachment to the Message object. One thought which occured to my mind was that may be the CDO library implements a lazy algorithm which builds the actual object only if it is sent or a stream is obtained from it etc. So i modified the code to add a Message.GetStream call to make sure that the attachment is actually loaded in to the Message object and the mime structure is built. Everything was fine. It buiilt the actual mime structure embedding the file. But still the reference was not released. It was very much evident because i was not even able to delete the file from the filesystem.

Finally i could conclude that the reference is still not released though the mime structure is built. Workaround was to get the stream from the object, create a temporary file, write the stream in it. Set the object to 'nothing', now the references are released here and the attached files are deleted . Create a new CDO Message object, load the stream from the saved file.

Well i dunno how far my approach of getting the job done was right. May be i am using the wrong approach, or it is indeed a bug in the CDO library which does not close the stream even after the mime structure is built.

Comments are welcome :)

No comments: