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
Related
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 used Redemption (http://dimastr.com/redemption/home.htm) for develop my Outlook AddIn. When I try GetMessageFromId in STA-thread(!) at first time all good, but in next times i get MAPI_E_UNKNOWN_ENTRYID.
RDOSession rdoSession = null;.
rdoSession = new RDOSession();
if (rdoSession != null)
{
if (!rdoSession.LoggedOn)
rdoSession.Logon(Consts.ProfileName);
if (rdoSession.LoggedOn)
{
for (int c = 1; c <= rdoStoresCnt; c++)
{
/* other code */
RDOMail mail = null;
try
{
mail = rdoSession.GetMessageFromID(entryID);
/* other code */
}
catch (Exception ex)
{
if (mail != null) Marshal.ReleaseComObject(mail); mail = null;
}
finally
{
if (mail != null) Marshal.ReleaseComObject(mail); mail = null;
}
}
}
}
What am I doing wrong?
MAPI_E_UNKNOWN_ENTRYID means the current MAPI session (created by calling RDOSession.Logon) does not know which MAPI provider is supposed to handle the specified entry id because (most likely) the provider has not been loaded yet in that session and did nto have a chance to register its set of entry ids with the MAPI system in the session.
You can try to specify the store entry id when calling GetMessageFromId (Redemption will open the specified store first and call IMsStore::OpenEntry instead of IMAPISession::OpenEntry), but the real solution is avoid creating a brand new MAPI session at all - since your code is inside Outlook, there is already the MAPI session used by Outlook: simply set the RDOSession.MAPIOBJECT property to Namespace.MAPIOBJECT from Outlook. Do not call RDOSession.Logoff in that case.
I am trying to add an external contact to global address list using EWS. So far I have failed to do so. Event newly added contact not visible in user primary contact list. Is there anything I am missing here? I have tried two version. One using EWS which is follow:
var service = InitConnection(exchangeUrl, exchangeUsername);
if (service == null)
{
return "Failed to connect to exchange server";
}
try
{
var data = (Hashtable)contactKeyValues;
if (data == null && data.Count <= 0)
{
return "The data can't be extracted. Please check your dictionary parameter of properties.";
}
var localExchangeContactObj = ValidateAndBuildContact(data);
var remoteExchangeContactObj = new Contact(service);
remoteExchangeContactObj.GivenName = localExchangeContactObj.FirstName;
remoteExchangeContactObj.Surname = localExchangeContactObj.LastName;
remoteExchangeContactObj.Initials = localExchangeContactObj.Initials;
remoteExchangeContactObj.FileAsMapping = FileAsMapping.GivenNameSpaceSurname;
remoteExchangeContactObj.PhoneNumbers[PhoneNumberKey.BusinessPhone] = localExchangeContactObj.PhoneBusiness;
remoteExchangeContactObj.PhoneNumbers[PhoneNumberKey.HomePhone] = localExchangeContactObj.PhoneHome;
remoteExchangeContactObj.EmailAddresses[EmailAddressKey.EmailAddress1] = localExchangeContactObj.Email;
var address = new PhysicalAddressEntry();
address.Street = localExchangeContactObj.Address;
address.City = localExchangeContactObj.City;
address.State = localExchangeContactObj.State;
address.PostalCode = localExchangeContactObj.Zip;
address.CountryOrRegion = localExchangeContactObj.Country;
remoteExchangeContactObj.PhysicalAddresses[PhysicalAddressKey.Business] = address;
remoteExchangeContactObj.Body = new MessageBody(BodyType.HTML, localExchangeContactObj.Notes);
remoteExchangeContactObj.Save(WellKnownFolderName.Contacts);
return remoteExchangeContactObj.Id.UniqueId.ToString();
}
catch (Exception exception)
{
return string.Format("Something went wrong while creating contact in exchnage. Here is the details {0}", exception.ToString());
}
The other approach is through LDAP, in which case it creates the contact in current OU, but dont show up while searching. Code as below:
try
{
DirectoryEntry de;
if (string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password))
{
de = new DirectoryEntry(ldapPath);
}
else
{
de = new DirectoryEntry(ldapPath, username, password);
}
var newContact = de.Children.Add("CN=" + name, "contact");
newContact.Properties["mail"].Value = email;
de.CommitChanges();
}
catch (COMException comEx)
{
var eventLog = new EventLog { Source = "Exchange Integration Create Contact" };
eventLog.WriteEntry(string.Format("Exception while creating contact {0} ", comEx), EventLogEntryType.Error);
return comEx.ErrorCode.ToString();
}
catch (Exception exception)
{
var eventLog = new EventLog { Source = "Exchange Integration Create Contact" };
eventLog.WriteEntry(string.Format("Exception while creating contact {0} ", exception), EventLogEntryType.Error);
return exception.ToString();
}
return "Contact created";
You can't create contacts in the GAL using EWS, EWS is a Mailbox Access API so you can create contacts in a Mailbox's contact folders which is what your code is trying to do. However these will not appear in the Global Address List. The only supported way to create contacts that will appear in the GAL is to use the Exchange Management Shell New-MailConact https://technet.microsoft.com/en-us/library/bb124519(v=exchg.150).aspx cmdlet and use Remote Powershell in your Managed code with https://msdn.microsoft.com/en-us/library/office/ff326159(v=exchg.150).aspx . This will create a Mail-enabled AD Contact. (Your LDAP code is creating a contact but it won't be mail enabled if you really want to go down the route you need to set a lot more properties such as TargetAddress etc look at existing Mail Enabled contact)
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.
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.