C# MailTo with Attachment? - c#

Currently I am using the below method to open the users outlook email account and populate an email with the relevant content for sending:
public void SendSupportEmail(string emailAddress, string subject, string body)
{
Process.Start("mailto:" + emailAddress + "?subject=" + subject + "&body="
+ body);
}
I want to however, be able to populate the email with an attached file.
something like:
public void SendSupportEmail(string emailAddress, string subject, string body)
{
Process.Start("mailto:" + emailAddress + "?subject=" + subject + "&body="
+ body + "&Attach="
+ #"C:\Documents and Settings\Administrator\Desktop\stuff.txt");
}
However this does not seem to work.
Does anyone know of a way which will allow this to work!?
Help greatly appreciate.
Regards.

If you want to access the default email client then you can use MAPI32.dll (works on Windows OS only).
Take a look at the following wrapper:
http://www.codeproject.com/KB/IP/SendFileToNET.aspx
Code looks like this:
MAPI mapi = new MAPI();
mapi.AddAttachment("c:\\temp\\file1.txt");
mapi.AddAttachment("c:\\temp\\file2.txt");
mapi.AddRecipientTo("person1#somewhere.com");
mapi.AddRecipientTo("person2#somewhere.com");
mapi.SendMailPopup("testing", "body text");
// Or if you want try and do a direct send without displaying the mail dialog
// mapi.SendMailDirect("testing", "body text");

mailto: doesn't officially support attachments. I've heard Outlook 2003 will work with this syntax:
<a href='mailto:name#domain.com?Subject=SubjTxt&Body=Bod_Txt&Attachment=""C:\file.txt"" '>
A better way to handle this is to send the mail on the server using System.Net.Mail.Attachment.
public static void CreateMessageWithAttachment(string server)
{
// Specify the file to be attached and sent.
// This example assumes that a file named Data.xls exists in the
// current working directory.
string file = "data.xls";
// Create a message and set up the recipients.
MailMessage message = new MailMessage(
"jane#contoso.com",
"ben#contoso.com",
"Quarterly data report.",
"See the attached spreadsheet.");
// Create the file attachment for this e-mail message.
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
// Add time stamp information for the file.
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(file);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
// Add the file attachment to this e-mail message.
message.Attachments.Add(data);
//Send the message.
SmtpClient client = new SmtpClient(server);
// Add credentials if the SMTP server requires them.
client.Credentials = CredentialCache.DefaultNetworkCredentials;
try {
client.Send(message);
}
catch (Exception ex) {
Console.WriteLine("Exception caught in CreateMessageWithAttachment(): {0}",
ex.ToString() );
}
data.Dispose();
}

Does this app really need to use Outlook? Is there a reason for not using the System.Net.Mail namespace?
If you really do need to use Outlook ( and I would not recommend it because then you're basing your app on 3rd party dependencies that are likely to change) you will need to look into the Microsoft.Office namespaces
I'd start here:
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.aspx

Try this
var proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = string.Format("\"{0}\"", Process.GetProcessesByName("OUTLOOK")[0].Modules[0].FileName);
proc.StartInfo.Arguments = string.Format(" /c ipm.note /m {0} /a \"{1}\"", "someone#somewhere.com", #"c:\attachments\file.txt");
proc.Start();

Related

SmtpException: Failure sending mail. Loop sending with Attachments

I have a console application that sends emails to several (12 currently) different email groups. The process loops through and each time creates a different excel workbook, saves the workbook, then sends an email with this workbook attached.
This process ran great for several months. Now, the program will make it through 2 emails, then it will throw an exception for Failure sending mail. I have found the inner exception is Unable to read data from the transport connection: net_io_connectionclosed
The workbooks are created via 2 SQL stored procs. Even when the email fails, the workbooks are created and can be opened so I don't think it has anything to do with the SQL involved.
I have seen several other SO issues for similar issues, but since my process works for 2, fails for 1, works for 2, fails for 1.... I believe my issue is different than a simple port or credentials issue.
Here is the code I have before loop to declare the SmtpClient
SmtpClient client = new SmtpClient("intmail.MyDomain.net", 25);
NetworkCredential cred = new NetworkCredential("myEmailAddress#email.com", "");
client.Credentials = cred; // Send our account login details to the client.
client.EnableSsl = false; // Read below.
Here is my code inside the loop for creating email, attaching workbook, and sending.
MailMessage msg = new MailMessage();
Attachment xls01 = new Attachment(filePath);
string emailTo = ClientEmail;
string[] emailTos = emailTo.Split(new char[] { ';' });
foreach (string To in emailTos)
{
msg.To.Add(To);
Console.WriteLine(To);
}
msg.From = new MailAddress("myEmailAddress#email.com");
//msg.CC.Add(new MailAddress("myEmailAddress#email.com"));
msg.Subject = ClientName + reportMonth + " " + reportYear;
msg.Body = "Attached is report for period ending on the last day of " + reportMonth + " " + reportYear + ".\r\nAlso attached are the 13 month trends.";
msg.Attachments.Add(xls01);
try
{
client.Send(msg);
}
catch (Exception ex)
{
Console.WriteLine(ex); //Should print stacktrace + details of inner exception
if (ex.InnerException != null)
{
Console.WriteLine("InnerException is: {0}", ex.InnerException);
}
}
Most likely you are hitting smtp server antispam filter when you sending messages one right after another. Try to space them apart in time and make 3 attempts for each send. Obviously you should not stop if any one send is failed, you should go through all 12.

How to add attachments to mailto in c#?

string email ="sample#gmail.com";
attachment = path + "/" + filename;
Application.OpenURL ("mailto:" +
email+"
?subject=EmailSubject&body=EmailBody"+"&attachment="+attachment);
In the above code, attachment isn't working. Is there any other alternative to add attachments using a mailto: link in C#?
mailto: doesn't officially support attachments. I've heard Outlook 2003 will work with this syntax:
<a href='mailto:name#domain.com?Subject=SubjTxt&Body=Bod_Txt&Attachment=""C:\file.txt"" '>
Your problem has already been answered:
c-sharp-mailto-with-attachment
You can use the System.Net.Mail which has the MailMessage.Attachments Property. Something like:
message.Attachments.Add(new Attachment(yourAttachmentPath));
OR
You can try like this:
using SendFileTo;
namespace TestSendTo
{
public partial class Form1 : Form
{
private void btnSend_Click(object sender, EventArgs e)
{
MAPI mapi = new MAPI();
mapi.AddAttachment("c:\\temp\\file1.txt");
mapi.AddAttachment("c:\\temp\\file2.txt");
mapi.AddRecipientTo("person1#somewhere.com");
mapi.AddRecipientTo("person2#somewhere.com");
mapi.SendMailPopup("testing", "body text");
// Or if you want try and do a direct send without displaying the
// mail dialog mapi.SendMailDirect("testing", "body text");
}
}
}
The above code uses the MAPI32.dll.
Source
It probably won't attach the document because you are at the liberty
of the email client to implement the mailto protocol and include
parsing for the attachment clause. You may not know what mail client
is installed on the PC, so it may not always work - Outlook certainly
doesn't support attachments using mailto.
A better way to handle this is to send the mail on the server using System.Net.Mail.Attachment.
public static void CreateMessageWithAttachment(string server)
{
// Specify the file to be attached and sent.
// This example assumes that a file named Data.xls exists in the
// current working directory.
string file = "data.xls";
// Create a message and set up the recipients.
MailMessage message = new MailMessage(
"jane#contoso.com",
"ben#contoso.com",
"Quarterly data report.",
"See the attached spreadsheet.");
// Create the file attachment for this e-mail message.
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
// Add time stamp information for the file.
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(file);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
// Add the file attachment to this e-mail message.
message.Attachments.Add(data);
//Send the message.
SmtpClient client = new SmtpClient(server);
// Add credentials if the SMTP server requires them.
client.Credentials = CredentialCache.DefaultNetworkCredentials;
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in CreateMessageWithAttachment(): {0}", ex.ToString());
}
data.Dispose();
}

Open New Outlook Message from C#

I am looking to generate an Outlook message from within my program, I am able to build and send from within the program or build and save, what I would like is to build then display to allow the user to manually select recipients from the AD listings... The code below is a mixup of samples here and other tutorial sites however none I can find just build then "display" the email without saving a draft or sending it from within the program...
also I am looking to find a way i can create a UNC link inside of an email IE: write out a path to the users folder \\unc\path\%USERNAME% or the likes
private void sendEmailOutlook(string savedLocation, string packageName)
{
try
{
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem oMsg = (Microsoft.Office.Interop.Outlook.MailItem)oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
oMsg.HTMLBody = "Attached is the required setup files for your <i><b>soemthing</i></b> deployment package.";
oMsg.HTMLBody += "\nPlease save this file to your network user folder located.<br /><br/>\\\\UNC\\data\\users\\%USER%\\";
oMsg.HTMLBody += "\nOnce saved please boot your Virtual machine, locate and execute the file at <br /> <br />\\\\UNC\\users\\%USER%\\";
int pos = (int)oMsg.Body.Length +1;
int attachType = (int)Microsoft.Office.Interop.Outlook.OlAttachmentType.olByValue;
Microsoft.Office.Interop.Outlook.Attachment oAttach = oMsg.Attachments.Add(savedLocation, attachType, pos, packageName);
oMsg.Subject = "something deployment package instructions";
oMsg.Save();
}
catch(Exception ex)
{
Console.WriteLine("Email Failed", ex.Message);
}
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem oMsg = (Microsoft.Office.Interop.Outlook.MailItem)oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
oMsg.Subject = "something deployment package instructions";
oMsg.BodyFormat = OlBodyFormat.olFormatHTML;
oMsg.HTMLBody = //Here comes your body;
oMsg.Display(false); //In order to display it in modal inspector change the argument to true
Regarding the link to the folder you should be able to use(in case that you know User Name):
Link
A lot of companies have their employees user names attached to address entries (looks something like "John Doe(Jdoe)" where Jdoe is a username).
when your user select a recipients or tries to send the email you could catch those event, and do something like
foreach (Outlook.Recipient r in oMsg.Recipients)
{
string username = getUserName(r.Name);// or r.AddressEntry.Name instead of r.Name
oMsg.HTMLBody += "<a href='C:\\Users\\" + username + "'>Link</a>"
}
oMsg.Save();
oMsg.Send();
where getUserName() is a method that extracts only the userName (Could use substring or RegEx).
Make sure that mail's body is a valid HTML
/n won't give you a new line you should use <br> insted.

System.Net.Mail.SmtpException: Insufficient system storage. The server response was: 4.3.1 Insufficient system resources

I've recently designed a program in C# that will pull information from SQL databases, write an HTML page with the results, and auto-email it out. I've got everything working [sporadically], the problem I'm having is that I seem to be crashing our company's exchange server. After the first few successful runs of the program, I'll start getting this exception:
Base exception: System.Net.Mail.SmtpException: Insufficient system storage. The server response was: 4.3.1 Insufficient system resources
I'm wondering if I should be calling some sort of Dispose()-like method in my mailing? Or if there is any other apparent reason that I would be causing the mail system to stop responding? This affects all clients in our company, not just my code.
This is Exchange 2010, and my code is compiled against .NET 3.5. My attachments are typically 27kb. If I log into the exchange server, it seems that messages just stick in a queue indefinitely. Clearing out the queue (remove without sending NDR) and rebooting the server will get it going again.
The mailing portions look like this (username, password, and address changed):
public void doFinalEmail()
{
List<string> distList = new List<string>();
string distListPath = Environment.CurrentDirectory + "\\DistList.txt";
string aLine;
logThat("Attempting email distribution of the generated report.");
if (File.Exists(distListPath))
{
FileInfo distFile = new FileInfo(distListPath);
StreamReader distReader = distFile.OpenText();
while (!String.IsNullOrEmpty(aLine = distReader.ReadLine()))
{
distList.Add(aLine);
}
}
else
{
logThat("[[ERROR]]: Distribution List DOES NOT EXIST! Path: " + distListPath);
}
MailMessage msg = new MailMessage();
MailAddress fromAddress = new MailAddress("emailaddresshere");
msg.From = fromAddress;
logThat("Recipients: ");
foreach (string anAddr in distList)
{
msg.To.Add(anAddr);
logThat("\t" + anAddr);
}
if (File.Exists(Program.fullExportPath))
{
logThat("Attachment: " + Program.fullExportPath);
Attachment mailAttachment = new Attachment(Program.fullExportPath);
msg.Attachments.Add(mailAttachment);
string subj = "Company: " + Program.yestFileName;
msg.Subject = subj;
msg.IsBodyHtml = true;
msg.BodyEncoding = System.Text.Encoding.UTF8;
sendMail(msg);
}
else
{
logThat("[[ERROR]]: ATTACHMENT DOES NOT EXIST! Path: " + Program.fullExportPath);
}
}
public void sendMail(MailMessage msg)
{
try
{
string username = "user"; //domain user
string password = "pass"; // password
SmtpClient mClient = new SmtpClient();
mClient.Host = "192.168.254.11";
mClient.Credentials = new NetworkCredential(username, password);
mClient.DeliveryMethod = SmtpDeliveryMethod.Network;
mClient.Send(msg);
}
catch (Exception oops)
{
string whatHappened = String.Format("Company: \r\nFailure in {0}! \r\n\r\nError message: {1} \r\nError data: {2} \r\n\r\nStack trace: {3} \r\n\r\nBase exception: {4} \r\nOccuring in method: {5} with a type of {6}\r\n", oops.Source, oops.Message, oops.Data, oops.StackTrace, oops.GetBaseException(), oops.TargetSite, oops.GetType());
logThat(whatHappened);
Environment.Exit(1);
}
}
This error can happen when:
The exchange server is out of disk space.
The recipient mailbox is out of disk space.
It is more common to run into issue #2 than issue #1.
Here is a list of Exchange Status Codes and their meanings.
To narrow down the issue definitively, you could swap in a different mail client like aspNetEmail (you can get an eval version to test), it wouldn't take but a few lines of code. If the problem persists, it is on the server; if not, it is on the client. I would strongly suspect this is a problem on the server, however, as when the client closes the connection and the message is sent, the server should really not be holding any resources as a result of that connection. You could verify this by looking at your SMTP logs and making sure there was no SMTP error when the connection was closed.
If this is indeed a problem on the server (the SMTP log shows clean disconnection and the problem is replicable with an alternate client), then I would log onto the server (if you can get access), and watch the disk space as jeuton suggests.
In exchange 2007 the c: (system drive) needs about 4GB of free disk space. This was our problem. Increment the drive and the mails will flow again.

Trying to Save Outlook Email in a Folder

I have a WinForms app that at the click of a button automatically produces an Outlook mail as follows:
public static void CreateOutlookEmail(string pFileName, string pCaseFolder, string pEmail, string pSubject, string pMessage)
{
try
{
Outlook.Application outlookApp = new Outlook.Application();
Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.Subject = pSubject;
mailItem.To = pEmail;
mailItem.Body = pMessage;
mailItem.Importance = Outlook.OlImportance.olImportanceNormal;
mailItem.Display(false);
string fileDetails = pCaseFolder + "\\" + pFileName + #".eml";
mailItem.SaveAs(fileDetails);
}
catch (Exception eX)
{
throw new Exception("cDocument: Error occurred trying to Create an Outlook Email"
+ Environment.NewLine + eX.Message);
}
}
The code succesfully opens a new Outlook email, and populates it with the details sent into the method e.g. email address, subject and the body of the message.
Also when I locate the folder (sent in as a paramater) I can see the email document has been saved.
The issue is, that when I open the email from the folder, the email document is totaly blank ii.e. no email address, subject or message.
What am I doing wrong?
Your code is fine. Just use extension ".msg" instead of ".eml". Also the eml format does not exist under Outlook.OlSaveAsType

Categories