I am trying to create Outlook Addin using C# by Customizing Application_ItemSend event of the Send button.
I need All the email details before sending an email.
When i run the below code # my home i get proper results by putting some personal email id its working.
But when i run this similar code in office outlook machine i get the names.
As by default outlook's check names code is enabled, this returns first and last name.
I am using Outlook 2010 # both the places. Office outlook is mapped to office active directory. my home outlook is not mapped. Can anyone provide a common solution which will give me all the email address used(to, cc, bcc & from) irrespective of active directory mapped or not.
private void ThisAddIn_Startup(object sender, System.EventArgs e) {
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
void Application_ItemSend(object Item, ref bool Cancel) {
Outlook.MailItem mail = Item as Outlook.MailItem;
Outlook.Inspector inspector = Item as Outlook.Inspector;
System.Windows.Forms.MessageBox.Show(mail.CC);
System.Windows.Forms.MessageBox.Show(mail.BCC);
}
Maybe is late, but someone can check this code (it's works for me)
private string[] GetCCBCCFromEmail(Outlook.MailItem email)
{
string[] ccBCC = new string[] { "", "" };//cc y bcc
Outlook.Recipients recipients = email.Recipients;
foreach (Outlook.Recipient item in recipients)
{
switch (item.Type)
{
case (int)Outlook.OlMailRecipientType.olCC:
ccBCC[0] += GetEmail(item.AddressEntry) + ";";
break;
case (int)Outlook.OlMailRecipientType.olBCC:
ccBCC[1] += GetEmail(item.AddressEntry) + ";";
break;
}
}
return ccBCC;
}
private string GetEmail(Outlook.AddressEntry address)
{
string addressStr = "";
if (address.AddressEntryUserType ==
Outlook.OlAddressEntryUserType.
olExchangeUserAddressEntry
|| address.AddressEntryUserType ==
Outlook.OlAddressEntryUserType.
olExchangeRemoteUserAddressEntry)
{
//Use the ExchangeUser object PrimarySMTPAddress
Outlook.ExchangeUser exchUser =
address.GetExchangeUser();
if (exchUser != null)
{
addressStr = exchUser.PrimarySmtpAddress;
}
}
//Get the address from externals
if (address.AddressEntryUserType == Outlook.OlAddressEntryUserType.
olSmtpAddressEntry)
{
addressStr = address.Address;
}
return addressStr;
}
Hope it helps
To/CC/BCC properties (corresponding to PR_DISPLAY_TO/CC/BCC in MAPI) are updated by the store provider when the item is saved (MailItem.Save). You can also access all recipients using the MailItem.Recipeints collection.
Related
I am writing a C# VSTO addin to provide some email filing helper functions. I am stuck as to how can programmatically move an email I have received into the conversations mailbox associated with an MS365 Group. The group itself is created as part of a sharepoint modern team site.
I can manually drag emails over to the group mailbox, but I cannot find a way to obtain the folder object in C#.
Microsoft® Outlook® for Microsoft 365 MSO (Version 2111 Build 16.0.14701.20254) 64-bit.
You can use the Move method of Outlook items.
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.NewMail += new Microsoft.Office.Interop.Outlook.
ApplicationEvents_11_NewMailEventHandler
(ThisAddIn_NewMail);
}
private void ThisAddIn_NewMail()
{
Outlook.MAPIFolder inBox = (Outlook.MAPIFolder)this.Application.
ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.Items items = (Outlook.Items)inBox.Items;
Outlook.MailItem moveMail = null;
items.Restrict("[UnRead] = true");
Outlook.MAPIFolder destFolder = inBox.Folders["Test"];
foreach (object eMail in items)
{
try
{
moveMail = eMail as Outlook.MailItem;
if (moveMail != null)
{
string titleSubject = (string)moveMail.Subject;
if (titleSubject.IndexOf("Test") > 0)
{
moveMail.Move(destFolder);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
I suppose the destination folder is listed in Outlook in an additional store. So, you can use the Stores property of the Namespace class to find the target folder.
I'm developing an Outlook Add-In in which I am trying to get a Calendar's Onwer Email Id in the Calenders ItemAdd Event. I had tried the method in the below post and it works for default accounts, but its not working when the Calendar is an Internet Calender Subscription.
Getting calendar's owner email address of an AppointmentItem
The AppointmentItem.Parent StoreID is not matching any Account Object in case of Internet Calendar. Is there any other way using which I can get the Calendar Owners email Address?
Thanks for your help!
I am using below code
GetCalendarOwner(Outlook.AppointmentItem appointment)
{
Outlook.MAPIFolder folder = appointment.Parent;
string email = "";
foreach (Outlook.Account account in Application.Session.Accounts)
{
Outlook.MAPIFolder folder2 = account.DeliveryStore.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
if (Application.Session.CompareEntryIDs(folder.Store.StoreID, account.DeliveryStore.StoreID))
{
Outlook.AddressEntry accountEmail = account.CurrentUser.AddressEntry;
if (accountEmail != null)
{
if (accountEmail.AddressEntryUserType ==
Outlook.OlAddressEntryUserType.olExchangeUserAddressEntry ||
accountEmail.AddressEntryUserType ==
Outlook.OlAddressEntryUserType.olExchangeRemoteUserAddressEntry)
{
Outlook.ExchangeUser exchUser = accountEmail.GetExchangeUser();
if (exchUser != null)
{
email = exchUser.PrimarySmtpAddress;
}
}
else
{
email = account.SmtpAddress;
if (string.IsNullOrEmpty(email))
{
email = accountEmail.Address;
}
}
}
break;
}
}
return email;
}
It is not clear what code exactly is used in the ItemSend event handler. Anyway, it seems you are interested in the MeetingItem.SendUsingAccount property that returns or sets an Account object that represents the account to use to send the MeetingItem.
You can use the SendUsingAccount property to specify the account that the Send method uses to send the MeetingItem. This property returns Null (Nothing in Visual Basic) if the account specified for the MeetingItem no longer exists or the default/primary one is used (see Namespace.CurrentUser).
I am using Microsoft.Office.Interop.Outlook in my C# code to read mail from PST file and I am facing issue when trying to get email address of sender.
I have tried the below code and I am getting email of the user who are there in the organization but not able to get the email of the users who left the organization or not active in AD.
string SenderEmailAddress = "";
try
{
AddressEntry sender = mail.Sender;
if (sender.AddressEntryUserType == OlAddressEntryUserType.olExchangeUserAddressEntry || sender.AddressEntryUserType == OlAddressEntryUserType.olExchangeRemoteUserAddressEntry)
{
ExchangeUser exchUser = sender.GetExchangeUser();
if (exchUser != null)
{
SenderEmailAddress = exchUser.PrimarySmtpAddress;
}
}
else
{
SenderEmailAddress = mail.SenderEmailAddress;
}
}
catch (System.Exception ex)
{
log.Log("Error Occured at getSenderEmailAddress() :: for " + mail.Sender + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace);
}
return SenderEmailAddress;
You should check SenderEmailType Property first.
_MailItem.SenderEmailType Property
Returns a String (string in C#) that represents the type of entry for the e-mail address of the sender of the Outlook item, such as 'SMTP' for Internet address, 'EX' for a Microsoft Exchange server address, etc. Read-only.
Please see also here.
Get the SMTP address of the sender of a mail item
To determine the SMTP address for a received mail item, use the SenderEmailAddress property of the MailItem object. However, if the sender is internal to your organization, SenderEmailAddress does not return an SMTP address, and you must use the PropertyAccessor object to return the sender’s SMTP address.
In the following code example, GetSenderSMTPAddress uses the PropertyAccessor object to obtain values that are not exposed directly in the Outlook object model. GetSenderSMTPAddress takes in a MailItem. If the value of the SenderEmailType property of the received MailItem is "EX", the sender of the message resides on an Exchange server in your organization. GetSenderSMTPAddress uses the Sender property of the MailItem object to get the sender, represented by the AddressEntry object.
private string GetSenderSMTPAddress(Outlook.MailItem mail)
{
string PR_SMTP_ADDRESS =
#"https://schemas.microsoft.com/mapi/proptag/0x39FE001E";
if (mail == null)
{
throw new ArgumentNullException();
}
if (mail.SenderEmailType == "EX")
{
Outlook.AddressEntry sender =
mail.Sender;
if (sender != null)
{
//Now we have an AddressEntry representing the Sender
if (sender.AddressEntryUserType ==
Outlook.OlAddressEntryUserType.
olExchangeUserAddressEntry
|| sender.AddressEntryUserType ==
Outlook.OlAddressEntryUserType.
olExchangeRemoteUserAddressEntry)
{
//Use the ExchangeUser object PrimarySMTPAddress
Outlook.ExchangeUser exchUser =
sender.GetExchangeUser();
if (exchUser != null)
{
return exchUser.PrimarySmtpAddress;
}
else
{
return null;
}
}
else
{
return sender.PropertyAccessor.GetProperty(
PR_SMTP_ADDRESS) as string;
}
}
else
{
return null;
}
}
else
{
return mail.SenderEmailAddress;
}
}
In Addition:
I misunderstood the question.
I do not have an answer to your question.
However, it seems that this can not be solved by the client side program.
Does the administrator need to do something?
The following article may be a hint for something.
Overview of inactive mailboxes in Office 365
Office 365 User Email Settings
Give mailbox permissions to another user in Office 365 - Admin Help
Convert a user mailbox to a shared mailbox
Open and use a shared mailbox in Outlook
I am currently refining an MS Outlook Add-In to pick up emails that end up in the Junk folder with "legit" addresses and then moving them into the Inbox folder.
This is an occurence that happens a lot for Gmail addresses, and is a bit painstaking for our staff members, who have to manually link those emails to their client accounts.
Has anyone attempted this? I have registered the incoming email event handler to read the Junk folder when an email comes in, but I keep getting an exception. I suspect it has to do with the fact that some of these emails are spam; which simply means that the MailItem will have lots of errors.
Has anyone had the same issue? Here is my code:
public void OutlookApplication_ItemReceived(string entryID)
{
//this.outlookNameSpace = this.application.GetNamespace("MAPI");
//Outlook.MAPIFolder inbox = this.outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
//Outlook.MAPIFolder junkFolder = this.outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderJunk);
if (Properties.Settings.Default.AutoLink || Properties.Settings.Default.EnableLeadLoader)
{
Outlook.MailItem mail = null;
try
{
this.Log("Email detected: incoming");
mail = this.application.Session.GetItemFromID(entryID) as Outlook.MailItem;
this.leadLoaderRecipient = Properties.Settings.Default.LeadLoaderRecipient.ToLower();
Outlook.Recipients recips = mail.Recipients; //That's where its crashing as the object is null... if read from spam folder
foreach (Outlook.Recipient recip in recips)
{
Outlook.PropertyAccessor pa = recip.PropertyAccessor;
string smtpAddress = pa.GetProperty(PR_SMTP_ADDRESS).ToString();
if (Properties.Settings.Default.EnableLeadLoader)
{
if (smtpAddress.ToLower() == this.leadLoaderRecipient)
this.ProcessLead(mail);
}
}
if (Properties.Settings.Default.AutoLink)
{
this.AutoLink(mail, true);
}
}
catch (Exception ex)
{
this.Log("Exception (ItemReceived): " + ex.ToString());
}
finally
{
if (mail != null)
{
Marshal.ReleaseComObject(mail);
}
}
}
}
Looking forward to your thoughts guys! :) TIA!
When exactly does your code run? Is that an Application.NewMailEx event handler? What is the exception?
Try to use the Items.ItemAdd event on the Junk Mail folder instead of using Application.NewMailEx.
I want to get the sender's emailId.
I am able to read all the data of calender by the below code but not the sender's emailId.
using Microsoft.Office.Interop.Outlook;
Microsoft.Office.Interop.Outlook.Application outlook = new Application();
Microsoft.Office.Interop.Outlook.NameSpace oNS = outlook.GetNamespace("MAPI");
oNS.Logon(Missing.Value, Missing.Value, true, true);
string currentUserEmail = oNS.CurrentUser.Address;
string currentUserName = oNS.CurrentUser.Name;
// Get the Calendar folder.
Microsoft.Office.Interop.Outlook.MAPIFolder objMAPIFolder =oNS.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
//Get the Sent folder
MAPIFolder sentFolder = oNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSentMail);
Items sentMailItems = sentFolder.Items;
Items items = objMAPIFolder.Items;
foreach (object item in sentMailItems)
{
if (item is MailItem)
{
MailItem oneMail = item as MailItem;
string mailContent = oneMail.HTMLBody;
//item.sender is not available
}
}
foreach (object item in items)
{
if (item is Microsoft.Office.Interop.Outlook.AppointmentItem)
{
Microsoft.Office.Interop.Outlook.AppointmentItem mitem = item as Microsoft.Office.Interop.Outlook.AppointmentItem;
string subject = mitem.Subject;
DateTime start = mitem.Start;
DateTime end = mitem.End;
string body = mitem.Body;
string location = mitem.Location;
string entryId = mitem.EntryID;
//sender email id not available
//string senderEmail = mitem.sender;
}
}
oNS.Logoff();
But in any case whether reading appointments or sent folder emails, I am unable to obtain the sender's email Id.
does anybody have any solution for this problem ?
I think you can get the name from mitem.organizser and then look at the Recipients to find the match..
Then look up the email address via a mapi property PR_SMTP_ADDRESS using a PropertyAccessor.
AppoitnmentItem.GetOrganizer() is not necessarily the sender of the appointment. In a shared calendar (chief/secretary), they might be different.
You can get the sender from an appointment using
AppointmentItem.SendUsingAccount
But from my experience (outlook 2010), that property returns null unless you are logged in as the sender. But it is useful to check if the organizer is different than the sender anyway.