This is the code that I am trying to use. But it isn't actually iterating the array to populate the body as I desire. What I want to do is use C# to create an outlook email, and populate the receiver, the Message Subject and then generate the Body of the email based of what is contained in the array. EDIT - I moved the for each loop to attempt to populate the body with each element of the array, but I get a compile error of unable to convert int to string with this code.
public static string GenerateEmail()
{
try
{
for (int q = eName.GetLowerBound(0); q <= eName.GetUpperBound(0); q++)
{
return Global.Variables.GlobalVariables.eName[q];
Outlook.Application oApp = new Outlook.Application();
Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
for (int q = eName.GetLowerBound(0); q <= eName.GetUpperBound(0); q++)
{
oMsg.HTMLBody = q;
}
oMsg.Subject = "Reports Are Ready";
Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients;
Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add("123123123#testemail.com");
oRecip.Resolve();
oMsg.Save();
oRecip = null;
oRecips = null;
oMsg = null;
oApp = null;
}
}
catch
{
}
return null;
}
}
The problem seems to be that the very first line in the for loop is a return statement, which causes the immediate abbortion of the function.
If you want to populate the message body instead of creating one message per interation, move the declaration of the actual e-mail outside the loop. Then inside the loop append the content to the message:
Outlook.Application oApp = new Outlook.Application();
Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
string content = string.Empty;
for (int q = eName.GetLowerBound(0); q <= eName.GetUpperBound(0); q++)
{
content += "...";
}
oMsg.HTMLBody = content;
// additional settings
Related
New to programming and trying to create this project for work. I have a text file inputted that has a list of usernames. I want the code to take the usernames from the text file and look them up in Outlook to give me a "true" or "false" if there is a match for the user in the system. How do I connect Outlook to the code with MAPI or an API? The code I have so far is below.
namespace QC_OUTLOOK
{
internal class Program
{
private static object MessageBox;
private static object objFile;
private static int i;
private static object Strings;
private static object response;
static int Main(string[] args)
{
string filePath = #"C:\Users\Documents\QC\User_list.txt";
// string[] lines = File.ReadAllLines(filePath);
List<string> lines = new List<string>();
lines = File.ReadAllLines(filePath).ToList();
using (StreamWriter streamWriter = File.CreateText(filePath));
foreach (String line in lines)
{
Console.WriteLine(line);
}
Console.ReadLine();
{
Outlook._Application oApp = new OutLook.Application();
//Get MAPI namespace
Outlook.AddressLists oNS = oNS.AddressLists;
Outlook.AddressList oGal = oALs.Item("Global Address List");
//Get all entries
Outlook.AddressEntries oEntries = oGal.AddressEntries;
// Get first user found
Outlook.AddressEntry oEntry = oEntries.GetFirst();
Outlook_UserName_Output = "";
response = sa.GetAllUsers;
Console.WriteLine(response);
//
UserCount = 0;
UsersFound = 0;
LastNameMatches = 0;
InactiveUser_Count = 0;
Inconsistent_EmailAddrs = 0;
GIS_UserCount = 0;
TodaysDate = DateTime.Today;
object value = objFile.WriteLine("Date:" + TodaysDate);
object value1 = objFile.WriteLine("QC_UserID, QC_FullName, OutLook_Last_Name, OutLook_First_Name");
for (i = 1; i <= Strings.Len(response) ; i++);
Outlook.Application oApp = new Outlook.Application();
// Get the MAPI namespace.
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
oNS.Logon(Missing.Value, Missing.Value, false, true);
Outlook.MAPIFolder oInbox = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
}
DataTable dt = new DataTable();
dt.Columns.Add("FirstName");
dt.Columns.Add("LastName");
Microsoft.Office.Interop.Outlook.Items OutlookItems;
Microsoft.Office.Interop.Outlook.Application outlookObj = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MAPIFolder Folder_Contacts = (MAPIFolder)outlookObj.Session.GetDefaultFolder(OlDefaultFolders.olFolderContacts);
OutlookItems = Folder_Contacts.Items;
foreach (var item in OutlookItems)
{
var contact = item as ContactItem;
if (contact != null)
{
DataRow dr = dt.NewRow();
dr["FirstName"] = contact.FirstName;
dr["LastName"] = contact.LastName;
dt.Rows.Add(dr);
}
First of all, creating a new Outlook Application instance multiple times in the code is not the best way to go:
Microsoft.Office.Interop.Outlook.Application outlookObj = new Microsoft.Office.Interop.Outlook.Application();
Outlook is a singleton. You can't run two instances of Outlook on the system at the same time. So, I'd suggest keeping the application object and re-use it where possible.
Iterating over all items in the Outlook folder is not really a good idea. Instead, use the Find/FindNext or Restrict methods of the Items class. Read more about these methods in the following articles:
How To: Retrieve Outlook Contact items using Restrict method
How To: Use Find and FindNext to retrieve Outlook Contact items
But better is to use the NameSpace.CreateRecipient method which creates a Recipient object and can be used to verify a given name against an address book. The Recipient.Resolve method attempts to resolve a created Recipient object against the Address Book. That's exactly what you are looking for!
I have to process Outlook calendar items in a C# application. My Problem: I have a self constructed Formula for Outlook Appointments and I whant to access to the data of this own Formula Region (created in the developer tab/Formulas).
Here my code without using the own fields:
Microsoft.Office.Interop.Outlook.Application oApp = null;
Microsoft.Office.Interop.Outlook.NameSpace mapiNamespace = null;
Microsoft.Office.Interop.Outlook.MAPIFolder CalendarFolder = null;
Microsoft.Office.Interop.Outlook.Items outlookCalendarItems = null;
oApp = new Microsoft.Office.Interop.Outlook.Application[];
mapiNamespace = oApp.GetNamespace("MAPI");
CalendarFolder = mapiNamespace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
outlookCalendarItems = CalendarFolder.Items;
outlookCalendarItems.IncludeRecurrences = true;
oApp = new Microsoft.Office.Interop.Outlook.Application[];
mapiNamespace = oApp.GetNamespace("MAPI");
foreach (Folder fold in mapiNamespace.Folders) {
if (folder.DefaultItemType == OlItemType.olAppointmentItem) {
foreach (Microsoft.Office.Interop.Outlook.AppointmentItem item in folder.Items) {
//Do stuff with the item (Subject, Location, Start, End, Categories)
//Also whant to access to item fields defined in own Formular here
}
}
}
The code works fine, but I don't know how to access the data of my selfconstructed formula fields.
Any ideas or different solutions?
Ok, found the property containing the Information:
For Each p As Microsoft.Office.Interop.Outlook.ItemProperty In item.ItemProperties
Try
MsgBox(p.Name & " " & p.Value.ToString())
'One of thousends of attributes
Catch e As System.Exception
End Try
Next
I've got the following code:
private void ListCalendarFolders(ref List<EBCalendar> items, int offset)
{
var pageSize = 100;
var view = new FolderView(pageSize, offset, OffsetBasePoint.Beginning);
view.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
view.PropertySet.Add(FolderSchema.DisplayName);
view.PropertySet.Add(FolderSchema.EffectiveRights);
view.Traversal = FolderTraversal.Deep;
FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot, view);
foreach (Folder myFolder in findFolderResults.Folders)
{
if (myFolder is CalendarFolder)
{
var folder = myFolder as CalendarFolder;
items.Add(EBCalendar.FromEWSFolder(folder));
}
}
if (findFolderResults.MoreAvailable)
{
offset = offset + pageSize;
ListCalendarFolders(ref items, offset);
}
}
Where service is an ExchangeService instance. Unfortunately, it still lists folders that have been deleted, and it doesn't list shared calendars.
How can I get it to list all the shared calendars, and how can I get it to not include the folders that have been deleted?
By Shared Calendars do you mean the calendars under the other calendars node in Outlook ?
If so these Items are NavLinks that are stored in the Common Views folder in a Mailbox which is under the NonIPMSubtree (root) see http://msdn.microsoft.com/en-us/library/ee157359(v=exchg.80).aspx. You can use EWS to get the NavLinks from a Mailbox and use the PidTagWlinkAddressBookEID extended property to get the X500 address of the Mailbox these Links refer to and then use Resolve Name to resolve that to a SMTP Address. Then all you need to do is Bind to that folder eg
static Dictionary<string, Folder> GetSharedCalendarFolders(ExchangeService service, String mbMailboxname)
{
Dictionary<String, Folder> rtList = new System.Collections.Generic.Dictionary<string, Folder>();
FolderId rfRootFolderid = new FolderId(WellKnownFolderName.Root, mbMailboxname);
FolderView fvFolderView = new FolderView(1000);
SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "Common Views");
FindFoldersResults ffoldres = service.FindFolders(rfRootFolderid, sfSearchFilter, fvFolderView);
if (ffoldres.Folders.Count == 1)
{
PropertySet psPropset = new PropertySet(BasePropertySet.FirstClassProperties);
ExtendedPropertyDefinition PidTagWlinkAddressBookEID = new ExtendedPropertyDefinition(0x6854, MapiPropertyType.Binary);
ExtendedPropertyDefinition PidTagWlinkGroupName = new ExtendedPropertyDefinition(0x6851, MapiPropertyType.String);
psPropset.Add(PidTagWlinkAddressBookEID);
ItemView iv = new ItemView(1000);
iv.PropertySet = psPropset;
iv.Traversal = ItemTraversal.Associated;
SearchFilter cntSearch = new SearchFilter.IsEqualTo(PidTagWlinkGroupName, "Other Calendars");
// Can also find this using PidTagWlinkType = wblSharedFolder
FindItemsResults<Item> fiResults = ffoldres.Folders[0].FindItems(cntSearch, iv);
foreach (Item itItem in fiResults.Items)
{
try
{
object GroupName = null;
object WlinkAddressBookEID = null;
// This property will only be there in Outlook 2010 and beyond
//https://msdn.microsoft.com/en-us/library/ee220131(v=exchg.80).aspx#Appendix_A_30
if (itItem.TryGetProperty(PidTagWlinkAddressBookEID, out WlinkAddressBookEID))
{
byte[] ssStoreID = (byte[])WlinkAddressBookEID;
int leLegDnStart = 0;
// Can also extract the DN by getting the 28th(or 30th?) byte to the second to last byte
//https://msdn.microsoft.com/en-us/library/ee237564(v=exchg.80).aspx
//https://msdn.microsoft.com/en-us/library/hh354838(v=exchg.80).aspx
String lnLegDN = "";
for (int ssArraynum = (ssStoreID.Length - 2); ssArraynum != 0; ssArraynum--)
{
if (ssStoreID[ssArraynum] == 0)
{
leLegDnStart = ssArraynum;
lnLegDN = System.Text.ASCIIEncoding.ASCII.GetString(ssStoreID, leLegDnStart + 1, (ssStoreID.Length - (leLegDnStart + 2)));
ssArraynum = 1;
}
}
NameResolutionCollection ncCol = service.ResolveName(lnLegDN, ResolveNameSearchLocation.DirectoryOnly, false);
if (ncCol.Count > 0)
{
FolderId SharedCalendarId = new FolderId(WellKnownFolderName.Calendar, ncCol[0].Mailbox.Address);
Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
rtList.Add(ncCol[0].Mailbox.Address, SharedCalendaFolder);
}
}
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
}
return rtList;
}
Cheers
Glen
You need to specify a searchfilter.
this is described here, though im not sure which Schema is the correct one, my guess would be Archieved.
So you would do something like this:
SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.Archieved, false);
FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot,searchFilter, view);
Glen post is perfect but binding folder gives error. However i solved this. Instead of this line:
Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
use the following line for shared folder binding
CalendarFolder calendar = CalendarFolder.Bind(service, new FolderId(WellKnownFolderName.Calendar, OwnerEmailAddress), new PropertySet());
Here OwnerEmailAddress is Email Address of Owner or you can write ncCol[0].Mailbox.Address if using Glen's code.
i m developing a Outlook Add ins using C#. hare i extract all the attachment(in doc or docx) which is attach with selected mail. i have create a button on tool bar using add in.when i click on button then all the attachment with selected mail come in to my database.now my question is that when i click on button that time some processing happens during the processing time i want to show a progress bar on my outlook window untill its finish extraction.Can any one help me to out this problem. here i include code also with extract mails attachment and sent to database
private void ThisApplication_NewMail()
{
DataTable dtImportedData = new DataTable();
Outlook.Explorer currExplorer = this.Application.ActiveExplorer();
Outlook.MAPIFolder folder = this.Application.ActiveExplorer().CurrentFolder;
Outlook.Items inBoxItems = folder.Items;
Outlook.MailItem item = null;
const string destinationDirectory = #"C:\TestFileSave";
if (!Directory.Exists(destinationDirectory))
{
Directory.CreateDirectory(destinationDirectory);
}
dtImportedData.Columns.Add("Select", typeof(bool));
dtImportedData.Columns.Add("Name");
dtImportedData.Columns.Add("Experience");
dtImportedData.Columns.Add("Company Name");
dtImportedData.Columns.Add("Email");
dtImportedData.Columns.Add("Mobile");
dtImportedData.Columns.Add("Date Of Birth");
dtImportedData.Columns.Add("Designation");
dtImportedData.Columns.Add("Location");
dtImportedData.Columns.Add("Qualification");
dtImportedData.Columns.Add("Skill Set");
dtImportedData.Columns.Add("Path");
//DataRow dr = null;
DataRow drExtract = null;
try
{
string strFileName = string.Empty;
Outlook.Selection selections = currExplorer.Selection;
for (int i = 1; i <= selections.Count; ++i)
{
object newEmail = (object)selections[i];
if (newEmail != null && (newEmail is Outlook.MailItem))
{
item = (Outlook.MailItem)newEmail;
if (item.Attachments.Count > 0)
{
for (int j = 1; j <= item.Attachments.Count; j++)
{
if (item.Attachments[j].FileName.Contains(".doc") || item.Attachments[j].FileName.Contains(".docx") || item.Attachments[j].FileName.Contains(".rtf"))
{
string filePath = Path.Combine(destinationDirectory, item.Attachments[j].FileName.ToString());
item.Attachments[j].SaveAsFile(filePath);
string m_Content = ClsWordManager.ReadWordFile(filePath);
drExtract = dtImportedData.NewRow();
ClsResumeExtractor objExtractResume = new ClsResumeExtractor();
drExtract["Select"] = true;
drExtract["Name"] = objExtractResume.ExtractName(m_Content);
drExtract["Email"] = objExtractResume.ExtractEmailAddressesFromString(m_Content);
drExtract["Mobile"] = objExtractResume.ExtractMobile(m_Content);
drExtract["Qualification"] = objExtractResume.ExtractQualification(m_Content);
drExtract["Designation"] = objExtractResume.ExtractDesignation(m_Content);
drExtract["Company Name"] = objExtractResume.ExtractCompanyName(m_Content);
drExtract["Location"] = objExtractResume.ExtractCurrentLocation(m_Content);
drExtract["Date Of Birth"] = objExtractResume.ExtractDateOfBirth(m_Content);
drExtract["Experience"] = objExtractResume.ExtractYearOfExperience(m_Content);
drExtract["Skill Set"] = objExtractResume.ExtractSkillSet(m_Content);
drExtract["Path"] = filePath;
dtImportedData.Rows.Add(drExtract);
}
}
}
else
{
System.Windows.Forms.MessageBox.Show("Select Email which have Attchments..!");
}
}
}
if (dtImportedData.Rows.Count > 0)
{
SaveImportedDataOutlook objSaveImportedDataOutlook = new SaveImportedDataOutlook();
objSaveImportedDataOutlook.grdCandidate.DataSource = dtImportedData;
ClsCommons.OpenDialog(objSaveImportedDataOutlook);
}
}
catch (Exception ex)
{
string errorInfo = (string)ex.Message.Substring(0, 11);
}
}
I'm trying to get Plain Text or HTML Text of email using AE.Net.Mail.
I cannot find any documentation.
using (Pop3Client pop3 = new AE.Net.Mail.Pop3Client("pop3Server", "login", "pwd", 995, true))
{
for (var i = pop3.GetMessageCount() - 1; i >= 0; i--)
{
MailMessage Msg = pop3.GetMessage(i);
string HtmlText = Msg.??????
string PlainText = Msg.??????
}
}
Edit : I found this solution
IList<Attachment> iList;
string HtmlText = "", PlainText = "";
for (var i = pop3.GetMessageCount() - 1; i >= 0; i--)
{
MailMessage msg = pop3.GetMessage(i);
TextBody = msg.Body;
iList = msg.AlternateViews as IList<Attachment>;
if (iList.Count == 0) iList = msg.Attachments as IList<Attachment>;
if (iList.Count > 0)
{
TextBody = iList[0].Body;
HtmlBody = iList[1].Body;
}
}
I solved this problem with this method:
Firt create a class:
class BodyContent
{
public string ContentType { get; set; }
public string Body { get; set; }
}
Than:
List<BodyContent> bodies = new List<BodyContent>();
foreach (AE.Net.Mail.Attachment item in mail.AlternateViews)
{
bodies.Add(new BodyContent
{
ContentType = item.ContentType,
Body = item.Body
});
}
And check has "text/html":
string body="";
BodyContent bodyTemp= bodies.Find(x => x.ContentType == "text/html");
if (bodyTemp== null)
body = mail.Body;
else
body = bodyTemp.Body;
And if has "text/html", body's format html else body's format plain
Body = e.Value.AlternateViews.GetHtmlView().Body,
If your MailMessage is the System.Net.Mail one, you can get the message body from the Body property. It may be either HTML or plain-text depending on the IsBodyHtml property. The AlternateViews property may also contain alternate forms of the message body.
you must set headers only to false
foreach (var item in mm)
{
Email myM = new Email();
myM.Date = item.Date;
myM.Body = item.Body;