C# save last send mail to desktop (as .msg) - c#

I am trying to save last send mail from Outlook to my desktop as .msg format.
But i am getting error with my code in last line of my code as follow:
((Microsoft.Office.Interop.Outlook.MailItem)mail).SaveAs(mydesktop+ "\\Myapplication\\" + subject.Replace(":", "").Replace("/", "").Replace("|", "") + ".msg", Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSG);
Error:System.Runtime.InteropServices.COMException: 'The item has been moved or deleted.'
string mailto = labelControl53.Text + ";" + labelControl56.Text ;
string cc = "myaccount#mymail.com";
string subject= labelControl7.Text + "-" + comboBoxEdit1.Text + "-" + textEdit6.Text + " Yüklemesi hk.";
string mydesktop= Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Microsoft.Office.Interop.Outlook.Application mailat = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem mail = (Microsoft.Office.Interop.Outlook.MailItem)mailat.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
mail.To = mailto;
mail.CC = cc;
mail.Subject = subject;
mail.Importance = Microsoft.Office.Interop.Outlook.OlImportance.olImportanceHigh;
mail.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
mail.HTMLBody = getHTMLupload();
((Microsoft.Office.Interop.Outlook.MailItem)mail).Send();
((Microsoft.Office.Interop.Outlook.MailItem)mail).SaveAs(mydesktop+ "\\Myapplication\\" + subject.Replace(":", "").Replace("/", "").Replace("|", "") + ".msg", Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSG);
System.Runtime.InteropServices.COMException: 'The item has been moved or deleted.'

This mail object is released after send so you don't have access to it.
You probably have to add an event handler. Something like this might work.
((Outlook.ItemEvents_10_Event)mail).Send += new Microsoft.Office.Interop.Outlook.ItemEvents_10_SendEventHandler(SaveSentMail);
static void SaveSentMail(ref bool Cancel)
{
mail.SaveAs(mydesktop+ ....);
}

If you want to save the last sent item in Outlook you need to handle the ItemAdd event of the Items class which comes from the Sent Items folder. Typically mail items are placed into the Sent Items folder as soon as they are sent. However, users or other add-ins may set the DeleteAfterSubmit property which sets a Boolean value that is True if a copy of the mail message is not saved upon being sent, and False if a copy is saved in Sent Items folder.
Or just call the SaveAs before submitting items in Outlook (before the Send method).

Related

Unable to send emails using Interop.Outlook

I'm working on a Selenium test which generates a report and then sends the report to an email address when it's finished. The script works flawlessly up until I have to send the email report.
The weird thing is that if I run the script from inside Visual Studio, the email sends fine, but when I build the solution and then set the script to run automatically from the task schedule it fails. The rest of the script runs fine, the report gets generated, it just doesnt send the email.
I'm not a Visual Studio expert, so I'm thinking it may possibly be something in my settings.
Here's the code to send the email using Outlook:
Outlook.Application oApp = new Outlook.Application();
Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
oMsg.HTMLBody = "Please find the attached Contract Remaining Hours report for the week of " + DateTime.Today.ToString("D");
String sDisplayName = fileName;
int iPosition = (int)oMsg.Body.Length + 1;
int iAttachType = (int)Outlook.OlAttachmentType.olByValue;
Outlook.Attachment oAttach = oMsg.Attachments.Add
(pathToFile + fileName, iAttachType, iPosition, sDisplayName);
oMsg.Subject = "Contract Remaining Hours Report " + DateTime.Today.ToString("D");
Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients;
Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add("tom.depiera#tbs.toshiba.com");
oRecip.Resolve();
oMsg.Send();

Retrieving Unread Emails with EWS C#

Below is my working code snippet that retrieves unread emails from custom folder names under Inbox.
foreach (Microsoft.Exchange.WebServices.Data.Folder folder in findFolderResults.Folders)
{
LogFile.AppendLog(folder.DisplayName + " folder found in Inbox.");
if (folder.DisplayName == folderName)
{
LogFile.AppendLog(folder.DisplayName + " matches " + folderName);
ItemView view = new ItemView(emailBatch);
do
{
LogFile.AppendLog("Checking for unread emails in folder " + folder.DisplayName);
emailItemList = service.FindItems(folder.Id, sf, view);
foreach (var emailItem in emailItemList.Items)
{
LogFile.AppendLog("Getting unread emails in folder " + folder.DisplayName);
EmailMessage email = EmailMessage.Bind(service, emailItem.Id);
retrievedEmailList.Add((EmailMessage)email);
}
if (!emailItemList.NextPageOffset.HasValue)
break;
}
while (emailItemList.MoreAvailable);
}
}
There is a variable emailBatch that is currently being configured as 10.
I do understand that this means that it will only check and retrieve 10 unread email at one go.
However, once the 10 email has been added to the list, will it continue to check for unread email?
I would need to add all unread emails to retrievedEmailList, instead of just 10 emails, if it happens.
Thank you.
You need to implement paged searching. You seem to have partially tried this but your code is missing some stuff. I have updated your code and put comments in explaining the new code I've added.
// Set the offset for the paged search.
int offset = 0;
// Set the flag that indicates whether to continue iterating through additional pages.
bool MoreItems = true;
LogFile.AppendLog(folder.DisplayName + " folder found in Inbox.");
if (folder.DisplayName == folderName)
{
// Continue paging while there are more items to page.
while (MoreItems)
{
LogFile.AppendLog(folder.DisplayName + " matches " + folderName);
// Set the ItemView with the page size and offset.
ItemView view = new ItemView(emailBatch, offset, OffsetBasePoint.Beginning);
LogFile.AppendLog("Checking for unread emails in folder " + folder.DisplayName);
emailItemList = service.FindItems(folder.Id, sf, view);
foreach (var emailItem in emailItemList.Items)
{
LogFile.AppendLog("Getting unread emails in folder " + folder.DisplayName);
EmailMessage email = EmailMessage.Bind(service, emailItem.Id);
retrievedEmailList.Add((EmailMessage)email);
}
// Set the flag to discontinue paging.
if (!emailItemList.MoreAvailable)
MoreItems = false;
// Update the offset if there are more items to page.
if (MoreItems)
offset += pageSize;
}
}

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.

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

C# MailTo with Attachment?

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

Categories