How to fetch attachment from outlook email in winforms? - c#

Microsoft.Office.Interop.Outlook.Application Application = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MAPIFolder inBox = Application.ActiveExplorer().Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
Microsoft.Office.Interop.Outlook.Items inBoxItems = inBox.Items;
Microsoft.Office.Interop.Outlook.MailItem newEmail = null;
foreach (object collectionItem in inBoxItems)
{
newEmail = collectionItem as Microsoft.Office.Interop.Outlook.MailItem;
if (newEmail != null)
{
if (newEmail.Attachments.Count > 0)
{
for (int i = 1; i <= newEmail
.Attachments.Count; i++)
{
newEmail.Attachments[i].SaveAsFile
(#"C:\TestFileSave\" +
newEmail.Attachments[i].FileName);
}
}
}
}
I have copy mail from outlook and paste into flex-grid in window application but getting zero attachment count but in mail there are attachments like excel , doc , etc. files.

int extractFileParentId = pkUniqueId;
List<ZipExtracFile> extractFileList = lts;
MsgReader.Outlook.Storage.Message message = new MsgReader.Outlook.Storage.Message(fileNames);
foreach (var attachment in message.Attachments)
{
string fileName = string.Empty;
pkUniqueId = pkUniqueId + 1;
if (attachment.GetType() == typeof(MsgReader.Outlook.Storage.Attachment))
{
var attach = (MsgReader.Outlook.Storage.Attachment)attachment;
fileName = Path.Combine(tempPath, (attach).FileName);
File.WriteAllBytes(fileName, attach.Data);
extractFileList.Add(new ZipExtracFile { pkUniqueId = pkUniqueId, fileName = fileName, parentId = extractFileParentId });
if(Path.GetExtension(fileName).ToLower() == ".msg")
{
ExtractMsgFile(fileName, ref pkUniqueId, ref tempPath, lts);
}
}
}
message.Dispose();
This is used to fetch documents from ".msg" file documents , with multilevel ".msg" file and it can download at specific location. For this need to add only MsgReader.dll

Related

Problem sending mail to mlutiple users in C#

Hi,
I'm trying to develop a wpf application for sending bulk email using Microsoft outlook app. I'm using a datagridview from which to, cc, and attachment will be extracted. Besides, for each mail, there'll be multiple to(s) and cc(s). If to and/or cc field contain single mail address, it works. But when multiple to or cc added, it gets the following error.
System.Runtime.InteropServices.COMException: 'Outlook does not recognize one or more names. '
I things it's issue with mail separation and put some efforts to resolve it.
Here's my datagridview data
Here's the code for sending mail.
private void BtnSendMail_Click(object sender, RoutedEventArgs e)
{
foreach (DataRowView rows in dgdData.ItemsSource)
{
try
{
Outlook.Application oApp = new Outlook.Application();
Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
Outlook.Recipients oRecips = oMsg.Recipients;
List<string> sTORecipsList = new List<string>();
List<string> sCCRecipsList = new List<string>();
var to = rows.Row.ItemArray[1].ToString();
var cc = rows.Row.ItemArray[2].ToString();
var attachment = rows.Row.ItemArray[3].ToString();
//var status = rows.Row.ItemArray[0] ="Sending";
if (to.Contains(",") || to.Contains(";") || to.Contains(" "))
{
string[] tos = Regex.Split(to, ",; ");
// string[] lines = Regex.Split(value, "\r\n");
for (int i = 0; i < tos.Length; i++)
{
//mail.To.Add(new MailAddress(tos[i]));
sTORecipsList.Add(tos[i]);
}
}
else
{
sTORecipsList.Add(to);
}
if (cc.Contains(",") || cc.Contains(";") || cc.Contains(" "))
{
string[] ccs = Regex.Split(cc, ",; ");
// string[] lines = Regex.Split(value, "\r\n");
for (int i = 0; i < ccs.Length; i++)
{
//mail.To.Add(new MailAddress(tos[i]));
sCCRecipsList.Add(ccs[i]);
}
}
else
{
sCCRecipsList.Add(cc);
}
oMsg.Body = "Sample Text";///rtbBody.Text.ToString();
string sDisplayName = "MyAttachment";
int iPosition = oMsg.Body.Length + 1;
int iAttachType = (int)Outlook.OlAttachmentType.olByValue;
Outlook.Attachment oAttach = oMsg.Attachments.Add(attachment, iAttachType, iPosition, sDisplayName);
oMsg.Subject = txtSubject.Text.ToString();
foreach (string t in sTORecipsList)
{
Outlook.Recipient recipTo = oMsg.Recipients.Add(t);
recipTo.Type = (int)Outlook.OlMailRecipientType.olTo;
}
foreach (string c in sCCRecipsList)
{
Outlook.Recipient recipCc = oMsg.Recipients.Add(c);
recipCc.Type = (int)Outlook.OlMailRecipientType.olCC;
}
oMsg.Recipients.ResolveAll();
Thread.Sleep(2000);
oMsg.Send();
rows.Row.ItemArray[0] = "Sent";
sTORecipsList = null;
sCCRecipsList = null;
//recipTo = null;
oRecips = null;
oAttach = null;
oMsg = null;
oApp = null;
Thread.Sleep(2000);
}
catch (Exception)
{
throw;
}
}
MessageBox.Show("All message sent!!");
}
Waiting for experts help. Thanks in advance.
Regards,
Subrata
The second argument to Regex.Split should be a regex pattern. So to match , or ; as a delimiter, you'd use a pattern like \s*[,;]\s* (the \s* allows optional whitespace around the delimiters):
string[] tos = Regex.Split(to, #"\s*[,;]\s*");
Note this uses the # symbol on the string to preserve the escapes.

How do i access an outlook account inbox using c#?

How do i access an outlook account inbox using c#? I've tried using the outlook object model and imap but it only displays the outlook account logged into my machine. I try logging into a different account with its username and password but it still logs into my local machine account. I read that logging out and closing outlook should fix this problem but it didn't change the results
Here is the code
using System;
using System.Reflection;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace ConsoleApplication1
{
public class Class1
{
public static int Main(string[] args)
{
try
{
Outlook.Application oApp = new Outlook.Application();
// Get the MAPI namespace.
Outlook.NameSpace oNS = oApp.GetNamespace("MAPI");
oNS.Logon("email address placeholder", "password placeholder", false, true);
//Get the Inbox folder.
Outlook.MAPIFolder oInbox = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
String user = oNS.CurrentUser.EntryID;
//Get the Items collection in the Inbox folder.
Outlook.Items oItems = oInbox.Items;
Console.WriteLine(oItems.Count);
Outlook.MailItem oMsg = (Outlook.MailItem)oItems.GetFirst();
Console.WriteLine(oMsg.Subject);
Console.WriteLine(oMsg.SenderName);
Console.WriteLine(oMsg.ReceivedTime);
Console.WriteLine(oMsg.Body);
int AttachCnt = oMsg.Attachments.Count;
Console.WriteLine("Attachments: " + AttachCnt.ToString());
if (AttachCnt > 0)
{
for (int i = 1; i <= AttachCnt; i++)
Console.WriteLine(i.ToString() + "-" + oMsg.Attachments[i].DisplayName);
}
for (int i = 0; i < oItems.Count; i++)
{
if (oItems.GetNext() is Outlook.MailItem)
{
oMsg = (Outlook.MailItem)oItems.GetNext();
Console.WriteLine(oMsg.Subject);
Console.WriteLine(oMsg.SenderName);
Console.WriteLine(oMsg.ReceivedTime);
Console.WriteLine(oMsg.Body);
AttachCnt = oMsg.Attachments.Count;
if (AttachCnt > 0)
{
for (int j = 1; j <= AttachCnt; j++)
Console.WriteLine(j.ToString() + "-" + oMsg.Attachments[j].DisplayName);
}
Console.WriteLine("Attachments: " + AttachCnt.ToString());
Console.WriteLine("CURRENT EMAIL # IS: " + i);
}
else
{
oItems.GetNext();
Console.WriteLine("NOT AN EMAIL");
Console.WriteLine("CURRENT EMAIL # IS: " + i);
}
}
oNS.Logoff();
oMsg = null;
oItems = null;
oInbox = null;
oNS = null;
oApp = null;
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught: ", e);
}
return 0;
}
}
}
You can try using this code:
public List<Outlook.MailItem> GetMails()
{
Microsoft,Office.Interop.Outlook.NameSpace nameSpace = OutLookName.Application.GetNameSpace("MAPI");
nameSpace.Logon("","",System.Reflection.Missing.Value,System.Reflection.Missing.Value);
Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = nameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
List<Outlook.MailItem> eMails = new List<Outlook.MailItem>();
foreach(Microsoft.Office.Interop.Outlook.MailItem mailItem in inboxFolder.Items)
{
if(mailItem.UnRead)
eMails.Add(mailItem);
}
return eMails;
}

Getting "Operation aborted " when using SaveAS method to save the mail item from outlook in c#

public void AccessOutlook()
{
Application oOutlook;
NameSpace oNs;
MAPIFolder oFldr;
try
{
oOutlook = new Application();
oNs = oOutlook.GetNamespace("MAPI");
oFldr = oNs.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
string str = "Total Mail(s) in Inbox:" + oFldr.Items.Count;
string str2 = "Total Unread items = " + oFldr.UnReadItemCount;
foreach (var oMessage in oFldr.Items)
{
MailItem mitem = null;
try
{
if (oMessage != null)
{
mitem = (MailItem)oMessage;
String savepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\" + "Sridhar.html";
mitem.BodyFormat = OlBodyFormat.olFormatHTML;
mitem.SaveAs(savepath, OlSaveAsType.olHTML);
}
}
catch (System.Exception ex)
{
}
if (mitem != null)
{
string str3 = mitem.Subject;
}
}
}
catch (System.Exception ex)
{
}
finally
{
GC.Collect();
oFldr = null;
oNs = null;
oOutlook = null;
}
}
Here I want to convert mail item into PDF, hence in first step I'm trying to get mail item based on subject line and saving it in any outlook supported file formats. But I'm not able to do. Can anyone help with this?
Thanks in advance

Accessing Outlook ost file

I have seen the difference between pst and ost files and currently working on accessing the outlook pst file through the following code given below.
Is there any way to use the same code for accessing ost file? Can someone refer me to this?
private DataTable GetInboxItems()
{
DataTable inboxTable;
//try
//{
filter = "[ReceivedTime] >= '" + dtpStartDate.Value.ToString("dd/MM/yyyy 12:00 AM") + "' and [ReceivedTime] <= '" + dtpEndDate.Value.ToString("dd/MM/yyyy 11:59 PM") + "'";
Outlook.Application outlookApp = GetApplicationObject();
Outlook.Folder root = outlookApp.Session.DefaultStore.GetRootFolder() as Outlook.Folder;
EnumerateFolders(root);
//string filter = "[ReceivedTime] > '" + dtpStartDate.Value.ToString("dd/MM/yyyy") + "'";
//inbox
Outlook.MAPIFolder inboxFolder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
inboxTable = CreateTable();
int count = 0;
if (inboxFolder.Items.Count > 0)
{
var restrictedItems = inboxFolder.Items.Restrict(filter);
restrictedItems.Sort("[ReceivedTime]", true); //descending
//foreach (var item in inboxFolder.Items)
foreach (var item in restrictedItems)
{
var mail = item as Outlook.MailItem;
if (mail != null)
{
//try
//{
DataRow row = inboxTable.NewRow();
//row["sn"] = (++count).ToString();
row["sn"] = mail.EntryID + " " + mail.ReceivedByEntryID;
row["MailType"] = "Inbox";
row["SenderName"] = mail.SenderName;
row["SenderEmail"] = mail.SenderEmailAddress;
row["ReceivedDate"] = mail.ReceivedTime;
row["Subject"] = mail.Subject;
row["Body"] = mail.Body != null ? (mail.Body.Length > 25 ? mail.Body.Substring(0, 25) : mail.Body) : null;
//row["Body"] = mail.Body != null ? mail.Body : "";
row["MailSize"] = mail.Size.ToString();
string attachments = null;
if (mail.Attachments.Count > 0)
{
foreach (var attachment in mail.Attachments)
{
if (((Outlook.Attachment)attachment) != null)
//attachments = ((Outlook.Attachment)attachment).FileName + " " + ((Outlook.Attachment)attachment).Size.ToString() + ", ";
attachments += (((Outlook.Attachment)attachment).Size / 1024).ToString() + " KB, ";
}
}
row["AttachmentCount"] = mail.Attachments.Count;
if (attachments != null)
row["AttachmentSize"] = attachments.Substring(0, attachments.Length - 2);
inboxTable.Rows.Add(row);
}
//catch (Exception ex)
//{
// return null;
//}
}
}
return inboxTable;
}
After I figured out how to actually build the code provided by OP, I found it very useful to get started on Outlook, so I would like to share the completed code below.
using System;
using System.Collections.Generic;//List
using System.Linq;//Array
//using System.Text;
//using System.Threading.Tasks;
using System.Diagnostics;//Process
using System.Runtime.InteropServices;//Marshal
using System.Data;//DataTable
using System.Reflection;//Missing
using Microsoft.Office.Interop.Outlook;//.OST files, needs Microsoft.Office.Interop.Outlook.dll
//TO DO: If you use the Microsoft Outlook 11.0 Object Library, uncomment the following line.
using Outlook = Microsoft.Office.Interop.Outlook;
namespace WatchOutlookMails
{
class StoreFormat
{
public DataTable GetInboxItems(DateTime dtpStartDate, DateTime dtpEndDate)
{
DataTable inboxTable;
string filter = string.Format("[ReceivedTime] >= '{0:dd/MM/yyyy 12:00 AM}' and [ReceivedTime] <= '{1:dd/MM/yyyy 11:59 PM}'", dtpStartDate, dtpEndDate);
Outlook.Application outlookApp = GetApplicationObject();
#if false//only needed if you want to select another folder
Outlook.Folder root = outlookApp.Session.DefaultStore.GetRootFolder() as Outlook.Folder;
EnumerateFolders(root);
#endif
//inbox
Outlook.MAPIFolder inboxFolder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
inboxTable = CreateTable();
if (inboxFolder.Items.Count > 0)
{
Items restrictedItems = inboxFolder.Items.Restrict(filter);
const bool SortDescending = true;
restrictedItems.Sort("[ReceivedTime]", SortDescending);
foreach (var item in restrictedItems)//item is a "COM Object" (?)
{
MailItem mail = item as Outlook.MailItem;
if (mail != null)
{
//try
//{
DataRow row = inboxTable.NewRow();
//row["sn"] = (++count).ToString();
row["sn"] = mail.EntryID + " " + mail.ReceivedByEntryID;
row["MailType"] = "Inbox";
row["SenderName"] = mail.SenderName;
row["SenderEmail"] = mail.SenderEmailAddress;
row["ReceivedDate"] = mail.ReceivedTime;
row["Subject"] = mail.Subject;
row["Body"] = mail.Body != null ? (mail.Body.Length > 25 ? mail.Body.Substring(0, 25) : mail.Body) : null;
//row["Body"] = mail.Body != null ? mail.Body : "";
row["MailSize"] = mail.Size.ToString();
int AttachmentSize = 0;
foreach (Outlook.Attachment attachment in mail.Attachments)
{
if (attachment != null)
AttachmentSize += attachment.Size;
}
row["AttachmentCount"] = mail.Attachments.Count;
row["AttachmentSize"] = AttachmentSize;
inboxTable.Rows.Add(row);
//catch (Exception ex)
//{
// break;
//}
}
}
}
return inboxTable;
}
private DataTable CreateTable()
{
DataTable T = new DataTable();
T.Columns.Add("sn", typeof(string));
T.Columns.Add("MailType", typeof(string));
T.Columns.Add("SenderName", typeof(string));
T.Columns.Add("SenderEmail", typeof(string));
T.Columns.Add("ReceivedDate", typeof(string));
T.Columns.Add("Subject", typeof(string));
T.Columns.Add("Body", typeof(string));
T.Columns.Add("MailSize", typeof(int));
T.Columns.Add("AttachmentCount", typeof(int));
T.Columns.Add("AttachmentSize", typeof(int));
return T;
}
private void EnumerateFoldersInDefaultStore()
{
Outlook.Application outlookApp = GetApplicationObject();
Outlook.Folder root = outlookApp.Session.DefaultStore.GetRootFolder() as Outlook.Folder;
EnumerateFolders(root);
return;
}
private void EnumerateFolders(Outlook.Folder folder)
{
Outlook.Folders childFolders = folder.Folders;
if (childFolders.Count > 0)
{
foreach (Outlook.Folder childFolder in childFolders)
{
// Write the folder path.
//Debug.WriteLine(childFolder.FolderPath);
// Call EnumerateFolders using childFolder.
// Uses recursion to enumerate Outlook subfolders.
EnumerateFolders(childFolder);
}
}
return;
}
/// <summary>
/// obtain an Application object that represents an active instance of Microsoft Outlook,
/// if there is one running on the local computer, or to create a new instance of Outlook,
/// log on to the default profile, and return that instance of Outlook
/// </summary>
/// <returns></returns>
private Outlook.Application GetApplicationObject()
{
// source: https://msdn.microsoft.com/en-us/library/ff462097.aspx
Outlook.Application application = null;
// Check whether there is an Outlook process running.
if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
{
// If so, use the GetActiveObject method to obtain the process and cast it to an Application object.
application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else
{
// If not, create a new instance of Outlook and log on to the default profile.
application = new Outlook.Application();
Outlook.NameSpace nameSpace = application.GetNamespace("MAPI");
nameSpace.Logon("", "", Missing.Value, Missing.Value);
nameSpace = null;
}
// Return the Outlook Application object.
return application;
}
}//end class
}//end ns
To fill in the missing pieces, I borrowed from https://support.microsoft.com/en-us/kb/310259, for EnumerateFolders: https://msdn.microsoft.com/en-us/library/office/ff184607.aspx
You need to educate yourself on what OST/PST is as the access to them is not much different, both are Store objects so they have the same interface.
Try this sources for a start and experiment yourself as it's the best way to understand how stuff works.
http://en.wikipedia.org/wiki/Personal_Storage_Table
http://msdn.microsoft.com/en-us/library/bb609139(v=office.14).aspx
http://msdn.microsoft.com/en-us/library/ff184648(v=office.14).aspx
http://msdn.microsoft.com/en-us/library/bb208208(v=office.12).aspx
http://www.c-sharpcorner.com/UploadFile/rambab/OutlookIntegration10282006032802AM/OutlookIntegration.aspx

Getting "process cannot access file" error when deleting files after sending email

I am getting error as mentioned below:
The process cannot access file "E:\TempPDFs\Sample.pdf" because it is being used by another process
I happen to send the pdf from email and after email is sent i need to delete the Sample.pdf file. The code that i have written doesn't work
FileInfo DeleteFileInfo = new FileInfo(directoryPath + "\\" + filename + ".pdf");
if (DeleteFileInfo.Exists)
File.Delete(directoryPath + "\\" + filename + ".pdf");
here directorypath is E:\TempPDFs, filename is Sample
UPDATED:
public static void SendMail(string fromAddress, string[] toAddress, string[] ccAddress, string[] bccAddress, string subject, string messageBody, bool isBodyHtml, ArrayList attachments, string host, string username, string pwd, string port)
{
{
try
{
if (isBodyHtml && !htmlTaxExpression.IsMatch(messageBody))
isBodyHtml = false;
// Create the mail message
MailMessage objMailMsg;
objMailMsg = new MailMessage();
if (toAddress != null)
{
foreach (string toAddr in toAddress)
objMailMsg.To.Add(new MailAddress(toAddr));
}
if (ccAddress != null)
{
foreach (string ccAddr in ccAddress)
objMailMsg.CC.Add(new MailAddress(ccAddr));
}
if (bccAddress != null)
{
foreach (string bccAddr in bccAddress)
objMailMsg.Bcc.Add(new MailAddress(bccAddr));
}
if (fromAddress != null && fromAddress.Trim().Length > 0)
{
//if (fromAddress != null && fromName.trim().length > 0)
// objMailMsg.From = new MailAddress(fromAddress, fromName);
//else
objMailMsg.From = new MailAddress(fromAddress);
}
objMailMsg.BodyEncoding = Encoding.UTF8;
objMailMsg.Subject = subject;
objMailMsg.Body = messageBody;
objMailMsg.IsBodyHtml = isBodyHtml;
if (attachments != null)
{
foreach (string fileName in attachments)
{
if (fileName.Trim().Length > 0 && File.Exists(fileName))
objMailMsg.Attachments.Add(new Attachment(fileName));
}
}
//prepare to send mail via SMTP transport
SmtpClient objSMTPClient = new SmtpClient();
if (objSMTPClient.Credentials != null)
{
}
else
{
objSMTPClient.UseDefaultCredentials = false;
NetworkCredential SMTPUserInfo = new NetworkCredential(username, pwd);
objSMTPClient.Host = host;
objSMTPClient.Port = Int16.Parse(port);
//objSMTPClient.UseDefaultCredentials = false;
objSMTPClient.Credentials = SMTPUserInfo;
//objSMTPClient.EnableSsl = true;
//objSMTPClient.DeliveryMethod = SmtpDeliveryMethod.Network;
}
//objSMTPClient.Host = stmpservername;
//objSMTPClient.Credentials
//System.Net.Configuration.MailSettingsSectionGroup mMailsettings = null;
//string mailHost = mMailsettings.Smtp.Network.Host;
try
{
objSMTPClient.Send(objMailMsg);
}
catch (SmtpException smtpEx)
{
if (smtpEx.Message.Contains("secure connection"))
{
objSMTPClient.EnableSsl = true;
objSMTPClient.Send(objMailMsg);
}
}
}
}
}
let me know if any query
Thanks!
Can we see a code that is responsible for sending a PDF file via e-mail? Your problem might be caused by not released memory stream. If you're using an Attachment class then you should do like the following:
using (Attachment data = new Attachment("document.pdf", MediaTypeNames.Application.Octet))
{
// 1. Adding attachment to the e-mail message
// 2. Sending out the e-mail message
}
The using statement will ensure that the Dispose method is called when the object gets out of the scope.
UPDATE
After calling the Send method make a call to Dispose of your mail message object:
objSMTPClient.Send(objMailMsg);
objMailMsg.Dispose();
Hope this will help you.
or better yet if the object implements IDisposable just write like this
((IDisposable)objSMTPClient).Dispose();

Categories

Resources