Launching email application (MAPI) from C# (with attachment) - c#

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.

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.

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

Bit lowtech method, but using the mailto handler you can do this
System.Diagnostics.Process.Start("mailto:something#somewhere.com?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.

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.

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);

Related

How to open default email client with attachment

I'm working on an issue to my project that when I click the button, a default email client should pop out and if there's an attachment, it should be automatically attach to the default email client like this.
I already tried a lot of methods how to do this. First I used MAPI, but the MAPI cannot detect my Default Email Client even though I already set it in Control Panel, It shows this two message box
I already searched the internet about those error but there's no definite or clear answer to me. HERE'S the code I used in MAPI.
I used also the mail:to protocol to call the default email client who's handling to the aforementioned protocol with using this line of codes.
Dim proc As System.Diagnostics.Process = New System.Diagnostics.Process()
Dim filename = Convert.toChar(34) & "C:\USERS\JOSHUA~1.HER\DOWNLO~1\ASDPOR~1.PDF" & Convert.toChar(34)
Debug.Writeline(filename)
Dim asd As String = String.Format("mailto:someone#somewhere.com?subject=hello&body=love my body&Attach={0}", filename)
proc.StartInfo.FileName = asd
proc.Start()
But still, no luck. I read a thread that the mail:to don't handle attachment anymore, but this line of code opened my default email client with body and subject, but there's no attachment. In terms of the filename variable, I already tried every path format, I read that I should use 8.3 path format. But still doesn't work.
The last method I used is extending the System.Net.MailMessage.MailMessage() following THIS answer. This works in terms of opening the default email client and attaching an attachment to a mail, but this is not editable and there's no send button on the default email client because this line of code just generating an .eml file and opening it. I'm thinking of parsing the eml file but still I don't know how to open the default email client progmatically in a new message form. Here's the photo
You guys have any idea how to make this possible? Thanks!
I am afraid that this will not be possible to do using some generic method for any mail client. But you can easily create your own solution using System.Net.Mail.SmtpClient and some simple custom UI.

Does Outlook need to be installed on server for Outlook Interop to work properly?

I am trying to open an email in Outlook from within a .NET application. When I run everything on my local machine it works just fine. When I deploy out to an IIS8 server I get an error on loading of the page. Does Outlook need to be installed on the server as well as the local client or does it just need to be on the client? When I comment out the below code everything loads just fine.
using Microsoft.Office.Interop.Outlook;
using Outlook = Microsoft.Office.Interop.Outlook;
protected void passdownBtn_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["ConnectionString"]);
{
SqlCommand comm = new SqlCommand("EXEC SvcGridEmail", conn);
conn.Open();
comm.ExecuteNonQuery();
string body = (string)comm.ExecuteScalar();
conn.Close();
string address = "bogus#email.com";
string time = String.Format("{0:MM/dd/yy HH:mm}", System.DateTime.Now);
string subject = "Service Jobs Passdown # " + time;
Outlook.Application oApp = new Outlook.Application();
Outlook._MailItem oMailItem = (Outlook._MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
oMailItem.To = address;
oMailItem.HTMLBody = body;
oMailItem.Subject = subject;
oMailItem.Display(true);
}
}
Yes it absolutely has to be installed. Outlook != Exchange.
You're using Outlook to automate "Outlook the application" - How can you do that if it isn't installed?
Automating Exchange is another story.
Are there any reasons other than the dependency on Outlook being installed
nonsense
1.1. when you run it on your box - it starts Outlook using your account with your permissions, when running on server under ASP.NET account - it may not open any account even Outlook will be installed there
1.2. how do you want to see a server application (Outlook) within an ASP.NET website, which works within a browser window?
1.3 sending an email message does not require Outlook. See How Can i Send Mail Through Exchange Server by using SMTP If message needs to be modified before being sent - create a webform.
licensing (I bet your organization has no server licence for MS Office)
As the others have told you Outlook must be installed if you want to use Outlook.Application.
However, from your comments I read that you want to open an Outlook instance on the client, not on your server. This is not possible using Outlook.Application. As I see it you have two possibilities:
Follow the suggestion of #Alex K.
Create a mailto link for your customer. If your customer clicks it it will open the default mailing program (does not need to be Outlook) on your customer's machine with the content you have defined.

How to include the user signature in the email body when sending a customized email through Thunderbird, using C# 3.5?

We need to send email from our desktop application using C# 3.5. The requirement is to send the new email using the Thunderbird, not directly from our application. So we are setting certain properties for the new email like emialfrom, emailto, subject, body & attachments through code, we save it as an .eml file & then we open that .eml file in thunderbird using code:
The logic we are following is:
MyEmailClass eml = new MyEmailClass();
eml.Subject = "subject";
eml.SetHtmlBody(" email body");
eml.From = "from";
email.AddTo = "toemail#domain.com";
email.AttachmentPath = "attachmentpath";
email.SaveEml("myEmail.eml");
So now we have the the .eml file & we need to open it in the Thunderbird, we are using System.Diagnostics.Process.Start to open the eml file in Thunderbird:
System.Diagnostics.Process.Start(thunderbird exe path,myEmail.eml path);
The above works fine, however we have just one issue, the sender signature is not shown when the email opens in the Thunderbird.
Facts:
1- The user has valid signature associated with his account.
2- We are using Thunderbird 8.0
3- We are using C# 3.5
4- Thunderbird is the default email client on users systems.
Signatures are added by the email client when it creates the email body. Since you are creating the email body through code, you would have to programmatically insert the signature. Just to be clear, you are not necessarily launching thunderbird on the user's machine, you are launching whatever process is associated with the .eml file extension. If you want to include the singature from Thunderbird, you could look to see if any of their APIs help, but they look like they haven't been updated in years. You could also give your users the option of setting up their signature within your application.

Generate an e-mail to be downloaded by client and sent from their outlook account

One of the requirements for the application that I'm working on is to enable users to submit a debugging report to our helpdesk for fatal errors (much like windows error reporting).
I've been told that e-mails must come from a client's mail account to prevent the helpdesk getting spammed and loads of duplicate calls raised.
In order to achieve this, I'm trying to compose a mail message on the server, complete with a nice message in the body for the helpdesk and the error report as an attachment, then add it to the Response so that the user can download, open and send it.
I've tried, without success, to make use of the Outlook Interoperability Component which is a moot point because I've discovered in the last 6 hours of googling that creating more than a few Application instances is very resource intensive.
If you want the user to send an email client side, I don't see how System.Net.Mail will help you.
You have two options:
mailto:support#domain.com?subject=Error&body=Error message here...
get user to download email in some format, open it in their client and send it
Option 1 will probably break down with complex bodies. With Option 2, you need to find a format that is supported by all mail clients (that your users use).
With option 1, you could store the email details locally on your server against some Error ID and just send the email with an Error ID in the subject:
mailto:support#domain.com?subject=Error 987771 encountered
In one of our applications the user hits the generate button and it creates and opens the email in outlook. All they have to do is hit the send button. The functions is below.
public static void generateEmail(string emailTo, string ccTo, string subject, string body, bool bcc)
{
Outlook.Application objOutlook = new Outlook.Application();
Outlook.MailItem mailItem = (Outlook.MailItem)(objOutlook.CreateItem(OlItemType.olMailItem));
/* Sets the recipient e-mails to be either sent by 'To:' or 'BCC:'
* depending on the boolean called 'bcc' passed. */
if (!(bcc))
{
mailItem.To = emailTo;
}
else
{
mailItem.BCC = emailTo;
}
mailItem.CC = ccTo;
mailItem.Subject = subject;
mailItem.Body = body;
mailItem.BodyFormat = OlBodyFormat.olFormatPlain;
mailItem.Display(mailItem);
}
As you can see it is outputting the email in plaintext at the moment because it was required to be blackberry friendly. You can easily change the format to HTML or richtext if you want some formatting options. For HTML use mailItem.HTMLBody
Hope this helps.
EDIT:
I should note that this is used in a C# Application and that it is referencing Microsoft.Office.Core and using Outlook in the Email class the function is located in.
The simple answer is that what you are trying to achieve isn't realistically achievable across all platforms and mail clients. When asked to do the improbable it is wise to come up with an alternative and suggest that.
Assuming that your fault report is only accessible from an error page then you've already got a barrier to spam - unless the spammers can force an exception.
I've always handled this by logging the fault and text into the database and integrating that with a ticketing system. Maybe also have a mailto: as Bruce suggest with subject=ID&body=text to allow the user to send something by email.
I don't think an .eml format file will help either - because they'll need to forward it, and most users would probably get confused.
A .eml is effectively plain text of the message including headers as per RFC-5322.

How to avoid Outlook security alert when reading outlook message from C# program

I have a requirement of reading subject, sender address and message body of new message in my Outlook inbox from a C# program. But I am getting security alert 'A Program is trying to access e-mail addresses you have stored in Outlook. Do you want to allow this'.
By some googling I found few third party COM libraries to avoid this. But I am looking for a solution which don't require any third party COM library.
I ran into same issue while accessing sender email address for outlook mail item. To avoid 'security alert' do not create new Application object, instead use Globals.ThisAddIn.Application to create new mailitem.
string GetSenderEmail(Outlook.MailItem item)
{
string emailAddress = "";
if (item.SenderEmailType == "EX")
{
Outlook.MailItem tempItem = (Outlook.MailItem)Globals.ThisAddIn.Application.CreateItem(Outlook.OlItemType.olMailItem);
tempItem.To = item.SenderEmailAddress;
emailAddress = tempItem.Recipients[1].AddressEntry.GetExchangeUser().PrimarySmtpAddress.Trim();
}
else
{
emailAddress = item.SenderEmailAddress.Trim();
}
return emailAddress;
}
Sorry, I have had that annoying issue in both Outlook 2003 and Outlook 2007 add-ins, and the only solution that worked was to purchase a Redemption license. In Outlook 2007 that pesky popup should only show up if your firewall is down or your anti-virus software is outdated as far as I recall.
Try this
Tools-->Macro-->Security-->Programmatic Access
Then choose Never warn me about suspicious activity.
"But I am looking for a solution which don't require any third party COM library."
You won't find it. Kasper already pointed out the only solution that I know of. Redemption has been the only thing that has kept the Outlook plug-ins and code to work. I have done commercial Outlook add-ins for Franklin Covey. We explored a lot things, but Redemption was the only thing that got us over this hurdle.
If your application is not a Outlook plug in you can look at MAPI to read data from the inbox
We use Advanced Security for Outlook from Mapilab for this. It is free, also for commercial use, and still keeps Outlook safe (by only allowing access from approved applications). Just apposed to previously mentioned solutions that cost either money, or may compromise security.
You can disable the security pop-up using Outlook's Trust Center.
Check here.

Categories