25

I have tried using mailItem.SenderEmailAddress and mailItem.Sender.Address but they both return a string that looks like this:

/O=DOMAINNAME/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHI43SPCLT)/CN=RECIPIENTS/CN=JOE BLOGGS8C3

Where in reality I want joebloggs@domainname.co.uk to be retrurned.

Anyone have any ideas?

Thank you very much.

Edit: I have done some digging; it works perfectly for email addresses of the 'SenderEmailType' SMTP, it just doesn't work for Exchange email addresses.

Edit 2: I have tried the code specified here, but I assume it is outdated because it throws a "Cannot create Active-X component" error.

EDIT 3: For anyone who ever has the same problem as me, I found the answer (in C#, converted to VB.NET, still works though):

Private Function GetSenderSMTPAddress(mail As Outlook.MailItem) As String
    Dim PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
    If mail Is Nothing Then
        Throw New ArgumentNullException()
    End If
    If mail.SenderEmailType = "EX" Then
        Dim sender As Outlook.AddressEntry = mail.Sender
        If sender IsNot Nothing Then
            'Now we have an AddressEntry representing the Sender
            If sender.AddressEntryUserType = Outlook.OlAddressEntryUserType.olExchangeUserAddressEntry OrElse sender.AddressEntryUserType = Outlook.OlAddressEntryUserType.olExchangeRemoteUserAddressEntry Then
                'Use the ExchangeUser object PrimarySMTPAddress
                Dim exchUser As Outlook.ExchangeUser = sender.GetExchangeUser()
                If exchUser IsNot Nothing Then
                    Return exchUser.PrimarySmtpAddress
                Else
                    Return Nothing
                End If
            Else
                Return TryCast(sender.PropertyAccessor.GetProperty(PR_SMTP_ADDRESS), String)
            End If
        Else
            Return Nothing
        End If
    Else
        Return mail.SenderEmailAddress
    End If
End Function
ubergorp
  • 263
  • 1
  • 3
  • 9

7 Answers7

34

I see you have answered your own question. I will post my C# function here incase anybody needs it or if you would like to use it as more help. My C# function for doing what you do looks like this:

 private string getSenderEmailAddress(Outlook.MailItem mail)
{
 Outlook.AddressEntry sender = mail.Sender;
 string SenderEmailAddress = "";

  if (sender.AddressEntryUserType == Outlook.OlAddressEntryUserType.olExchangeUserAddressEntry || sender.AddressEntryUserType == Outlook.OlAddressEntryUserType.olExchangeRemoteUserAddressEntry)
    {
        Outlook.ExchangeUser exchUser = sender.GetExchangeUser();
        if (exchUser != null)
        {
            SenderEmailAddress = exchUser.PrimarySmtpAddress;
        }
    }
    else
    {
        SenderEmailAddress = mail.SenderEmailAddress;
    }

    return SenderEmailAddress;
}
Community
  • 1
  • 1
Alex
  • 1,052
  • 7
  • 19
  • Copy and pasted this exactly, used it with a mail item and got this `System.NullReferenceException, HResult=0x80004003, Message=Object reference not set to an instance of an object.` on the if statement. – user2924019 Nov 24 '20 at 22:01
  • @user2924019 That should only happen if the email you try to process does not have a sender which means the sender object you try to validate is null. – SysC0mp Feb 15 '21 at 08:41
  • @SysC0mp There was a sender, the email was an email in the inbox. It was difficult finding a solution that worked reliably (with secondary mailboxes, exchange / non exchange) but I managed to get it working in the end. – user2924019 Feb 15 '21 at 16:47
9

VBA Solution as well (Just translated the VB.net)

Private Function GetSenderSMTPAddress(mail As Outlook.MailItem) As String

    If mail Is Nothing Then
        GetSenderSMTPAddress = vbNullString
        Exit Function
    End If
    If mail.SenderEmailType = "EX" Then
        Dim sender As Outlook.AddressEntry
        Set sender = mail.sender
        If Not sender Is Nothing Then
            'Now we have an AddressEntry representing the Sender
            If sender.AddressEntryUserType = Outlook.OlAddressEntryUserType.olExchangeUserAddressEntry Or sender.AddressEntryUserType = Outlook.OlAddressEntryUserType.olExchangeRemoteUserAddressEntry Then
                'Use the ExchangeUser object PrimarySMTPAddress
                Dim exchUser As Outlook.ExchangeUser
                Set exchUser = sender.GetExchangeUser()
                If Not exchUser Is Nothing Then
                     GetSenderSMTPAddress = exchUser.PrimarySmtpAddress
                Else
                    GetSenderSMTPAddress = vbNullString
                End If
            Else
                 GetSenderSMTPAddress = sender.PropertyAccessor.GetProperty(PR_SMTP_ADDRESS)
            End If
        Else
            GetSenderSMTPAddress = vbNullString
        End If
    Else
        GetSenderSMTPAddress = mail.SenderEmailAddress
    End If
End Function
LimaNightHawk
  • 6,613
  • 3
  • 41
  • 60
Gerry Wilton
  • 91
  • 1
  • 2
9

If someone's still looking for a solution to this problem, here is a simplified and true-blue VBA version of the code to handle this requirement.

Public Sub GetCurrentItem()
    On Error Resume Next
    Set ObjSelectedItem = Outlook.ActiveExplorer.Selection.Item(1)
    If TypeName(ObjSelectedItem) = "MailItem" Then
        If ObjSelectedItem.SenderEmailType = "EX" Then
            MsgBox (ObjSelectedItem.Sender.GetExchangeUser.PrimarySmtpAddress)
        Else
            MsgBox (ObjSelectedItem.SenderEmailAddress)
        End If
    Else
        MsgBox ("No items selected (OR) Selected item not a MailItem.")
    End If
    Set ObjSelectedItem = Nothing
End Sub
prgSRR
  • 169
  • 4
  • 11
8

To me a much simpler answer is as follows

Where to get an external address you may have used SenderEmailAddress, then for an internal (i.e. from exchange) address use Sender.GetExchangeUser.PrimartySmtpAdress instead

If you want it to work for both internal and external addresses then put in a test to see whether the address was internal or external first. Example code snippet below

If itm.SenderEmailType = "SMTP" Then
        mailfrom = itm.SenderEmailAddress
Else
If itm.SenderEmailType = "EX" Then
        mailfrom = itm.Sender.GetExchangeUser.PrimarySmtpAddress
End If
End If
larcy
  • 101
  • 1
  • 4
0

In C# you can access the sender's email address using the SendUsingAccount.SmtpAddress property of the Outlook MailItem. It returns a string object. VB.net should be similar.

string sender = mail.SendUsingAccount.SmtpAddress;

where mail is an Outlook.MailItem

riQQ
  • 9,878
  • 7
  • 49
  • 66
Frank
  • 9
  • 1
  • voted down because this provides my address for every message rather than the sender's email address. – Eric Dec 13 '22 at 23:40
0

Here's the python version using pywin32:

import win32com.client
if(message.SenderEmailType == "EX"):
    sender_email = message.Sender.GetExchangeUser().PrimarySmtpAddress
Eric
  • 1,392
  • 17
  • 37
-1

Created a VBA function if you wanted to use it for simplicity. A sample call would be Left(GetEmailAddress(mai) & Space(50), 50) where mai is expected to be a MailItem object. Used and tested successfully in Microsoft Outlook 2010

Public Function GetEmailAddress(mai As Object) As String
    On Error Resume Next
    Set ObjSelectedItem = mai
    If TypeName(ObjSelectedItem) = "MailItem" Then
        If ObjSelectedItem.SenderEmailType = "EX" Then
            GetEmailAddress = ObjSelectedItem.Sender.GetExchangeUser.PrimarySmtpAddress
        Else
            GetEmailAddress = ObjSelectedItem.SenderEmailAddress
        End If
    Else
        GetEmailAddress = "Not a MailItem"
    End If

    Set ObjSelectedItem = Nothing
    End Function