views:

7437

answers:

5

In the past I have used MAPISendMail to launch Outlook (or whatever the desired MAPI email application was) from a C++ application with a file attachment. (Similar to say Microsoft Word's Send Email functionality).

I need to do the equivalent from a C# application and to have it work when running on XP, Vista, Server 2008 (and Windows 7 I suppose).

MAPISendMail is a no go under Vista/2008 as it always returns MAPI_ E_FAILURE when Outlook is running and MAPI is not supported in managed code. Even after checking this fix: http://support.microsoft.com/kb/939718 I can't get it to reliably work.

I know that Microsoft Word & Adobe Reader 9 can both launch Outlook with an attachment under Vista.

A C# compatible solution would be preferred but I'd be happy with anything that works (doesn't have to use MAPI). I can't seem to find what the current "solution" is. None of the existing answers on Stack Overflow seem to cover this either.

Edit:

I am aware MAPI and C# do not work together, so I will take a C/C++ solution that works in Vista and Server 2008 when NOT running as administrator. See Adobe Reader 9 & Microsoft Word as examples that work.

A: 

Bit lowtech method, but using the mailto handler you can do this

System.Diagnostics.Process.Start("mailto:[email protected]?subject=hello&attachment=c:\\chicken.xls");

Note: As pointed out this may not work on all clients as it is not part of the mailto URL spec. Most importantly (in my world at least) is Outlook 2007 does not support it, while older versions did.

Robert MacLean
Unfortunately attachments don't work via mailto.
Steven
@Steven, usage is dependant on the mail client. Outlook 2007 for instance doesn't support it, while older versions did.
Robert MacLean
@Steven, I've updated the answer to reflect this as I do think it is a useful answer with the risks identified.
Robert MacLean
Yeah, it used to be easy to do this.
Steven
+5  A: 

At work we have successfully done this using VSTO.

Here is a snippet of some lines we have running on VISTA with Outlook 2007: (the code is in VB.net).

Note that the usage is security locked when doing certain things to the outlook object. (to address, body and other properties marked as security risks). We use a 3rd party component (Redemption) to go around this security. If you dont use a security manager of some sort, outlook will give a little popup that something outside is trying to access it and you can give it access in a period of time.

The import of the Outlook interface.

Imports Outlook = Microsoft.Office.Interop.Outlook

This example is to give you some direction, not a full working example.

dim MailItem As Microsoft.Office.Interop.Outlook.MailItem

' Lets initialize outlook object '
MailItem = OutlookSession.Application.CreateItem(Outlook.OlItemType.olMailItem)
MailItem.To = mailto

MailItem.Subject = communication.Subject
MailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML
MailItem.HTMLBody = htmlBody

MailItem.Attachments.Add(filename, Outlook.OlAttachmentType.olByValue)

' If True is supplied to Display it will act as modal and is executed sequential. '
SafeMail.Display(True)

The OutlookSession in the above example is coming from this Property:

    Public ReadOnly Property OutlookSession() As Outlook.NameSpace
        Get
            If Not OutlookApplication Is Nothing Then
                Return OutlookApplication.GetNamespace ("MAPI")
            Else
                Return Nothing
            End If
        End Get
    End Property

As you can see it is using MAPI inside for this.

Good luck with it.

AnotherDan
With Outlook 2007 on Vista if you have an active Anti-Virus program running, you will not get the Outlook security prompts.
Dennis Palmer
I will test this and see if it works, thanks.
Steven
+2  A: 

I'm not sure if you need the email to open in outlook or if you just want to send an email with an attachment from c#. I know you wrote open in outlook but you may be assuming this is the only way to do it. If you just want to send an email with an attachment it can be done something like below.

#using System.Net.Mail;

SmtpClient smtpClient = new SmtpClient(host, port);

MailMessage message = new MailMessage(from, to, subject, body);
Attachment attachment = new Attachment(@"H:\attachment.jpg");
message.Attachments.Add(attachment);

System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential(username, password);
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = SMTPUserInfo;
smtpClient.Send(message);

You can also do it without the authentication bit depending on your email server.

PeteT
A: 

C# code to send email through outlook ; No security warnings occur

var outlook = new ApplicationClass(); MailItem mailItem = (MailItem)outlook.Session.Application.CreateItem(Outlook.OlItemType.olMailItem);

mailItem.Display(false);

Sanjay10
A: 

You don't really need redemption for VB as suggested above as long as you are simply setting properties in an e-mail and not reading them. Here is a simple VB function to show / send an e-mail via outlook with an attachment. (This code references the Microsoft Outlook 12.0 Object Library e.g. "C:\Program Files\Microsoft Office\Office12\MSOUTL.OLB").

Sub DoMail()
    Set objOL = CreateObject("Outlook.Application")
    Set objNewMail = objOL.CreateItem(olMailItem)

    Dim filename As String
    filename = "C:\\temp\\example.txt"

    With objNewMail
        .To = "cjoy@spam_me_not.com"
        .Subject = "test"
        .Body = "Test Body"
        .Attachments.Add filename, Outlook.OlAttachmentType.olByValue
    End With

    objNewMail.Display

    'objNewMail.Send
End Sub
One more comment. If you are working in visual C++, MFC has a method to simply send an e-mail with a document attached using MAPI. The method is CDocument::OnFileSendMail(). This code is also easy to adapt to create your own "send e-mail with attachement" via MAPI.