Almost a year ago, I was bemoaning the fact that sending email is hard. Well, recently, my client went from a PC to a Mac, and he needed some help installing the program in the virtual XP session. When I was there, I set up the Outlook Express client so that the PDF statements could be emailed out from the virtual XP world. I figured that, since I know his email client, perhaps I could find something specific to that client for sending email.
Googling around for sending email from C# with Outlook Express, I eventually came across this CodeProject article: Programmatically adding attachments to emails in C# and VB.NET. I took the code and dropped it into my project pretty much as-is. My development machine is now a Windows Vista laptop, but this code worked just fine, starting up a Windows Live Mail window with the file attached.
There were a couple issues. One, if Live Mail wasn't started first, then I'd get an error from the MAPI call — apparently the client needs to be initialized before the call is made. (The MAPI call was starting Live Mail, but Live Mail did not appear to be in a ready state then the email was sent to it.) The second is that the SendMailPopup call (which is the one I want) blocks until the email message is closed (i.e. sent or discarded). The comments in that article, however, mention a method to split that call onto another thread, so I should be able to prepare and open several emails at once.
So I think I will create a configuration parameter that will allow the toggling of attempting to use MAPI. It should work, but it'll be preferable to have something to fall back on.
Incidentally, a discussion thread over at Channel 9 pretty much summed up the problem as such:
- If you have Outlook, you can do it. (Use Outlook automation)
- If you have a MAPI profile (e.g. Outlook Express), you can do it.
- If you have SMTP, you can do it. (System.Web.Mail standard)
To which I'll add:
- If you don't know what you have, you can try it. (mailto: link, attachments not supported)
Just for kicks, I tried this on my PC at work, which is running XP and has the Mozilla Thunderbird email client installed. It worked beautifully, whether I had Thunderbird running before I called SendMailPopup or not. I don't know if Outlook would also respond to this code or not. (I'll have to try the compiled program on my desktop with Outlook when I'm done.) If so, it could simplify things, as much as they can be considered "simplified" in what seems to be a complicated situation.
At least I'm in the fortunate situation that I'm writing this for a known, single client and a known configuration.
I do wonder why there's not a managed MAPI wrapper though. For my own convenience, I'm gathering emails into a collection of System.Web.Mail.MailMessage objects before I try sending them. Why is there no System.Web.Mail.Mapi.Send method? Maybe a System.Web.Mail.Mapi.IsClientRunning method, and so on.