'is there a way to get the smtpaddress for an mapifolder or outlook interop folder given the entryid (or storeid)

if i have the storeid for a mapifolder, selected through the folderpicker from the outlook interop libraries, is there a way for me to get the smtpaddress for that folder?

i know it's in the extended properties, but i was hoping to do it without any heavy parsing or ldap querying.

the reason i need the smtpaddress is in order to connect to the folder via EWS - i'm currently trying to replace our references to outlook interop with exchange web services, and this has become a sticking point, since many of our users have delegate access to mailboxes that don't belong to them



Solution 1:[1]

For the mailbox owner, you can either try to read the MAPIFolder.Store property to get to the parent store, then read the PR_MAILBOX_OWNER_ENTRYID property (DASL name "http://schemas.microsoft.com/mapi/proptag/0x661B0102") using Store.PropertyAccessor.GetProperty. You can then use the store owner entry id to call Namespace.GetAddressEntryFromID. Once you have the AddressEntry object, you can use AddressEntry.GetExchangeUser.PrimarySmtpAddress.

Note that PR_MAILBOX_OWNER_ENTRYID property is only available in the online stores. You might want to use Redemption (I am its author) and its RDOExchangeMailboxStore.Owner.SmtpAddress property. RDOExchangeMailboxStore can be retrieved using RDOSession.GetRDOObjectfromOutlookObject(Store) or using RDOSession.GetStoreFromID.

Solution 2:[2]

I know it's years later (sorry), but I needed get SMTP addresses for a bunch of mailboxes, and the accepted answer didn't work (because I've got offline stores) so I did the parsing.

public static bool TryGetSmtpAddress(MAPIFolder folder, out string smtpAddress)
{
    smtpAddress = default;

    var storeId = HexToBytes(folder.StoreID);

    // check it's a store entry id
    if (BitConverter.ToUInt64(storeId, 4) != 0x1A10E50510BBA138UL
        || BitConverter.ToUInt64(storeId, 12) != 0xC2562A2B0008BBA1UL) { return false; }

    var indexDn = Array.IndexOf(storeId, (byte)0x00, 60) + 1;
    var indexV3Block = Array.IndexOf(storeId, (byte)0x00, indexDn) + 1;

    // check it's a V3 entry id (with SMTP address)
    if (BitConverter.ToUInt32(storeId, indexV3Block) != 0xF43246E9UL) { return false; }

    var offsetSmtpAddress = BitConverter.ToUInt32(storeId, indexV3Block + 12);

    smtpAddress = BytesToUnicode(storeId, indexV3Block + (int)offsetSmtpAddress);
    return true;
}

private static byte[] HexToBytes(string input)
{
    var bytesLength = input.Length / 2;
    var bytes = new byte[bytesLength];
    for (var i = 0; i < bytesLength; i++) { bytes[i] = Convert.ToByte(input.Substring(i * 2, 2), 16); }
    return bytes;
}

private static string BytesToUnicode(byte[] value, int startIndex)
{
    var charsLength = (value.Length - startIndex) / 2;
    var chars = new char[charsLength];
    for (var i = 0; i < charsLength; i++)
    {
        var c = chars[i] = BitConverter.ToChar(value, startIndex + i * 2);
        if (c == '\0') { return new String(chars, 0, i); }
    }
    return new String(chars);
}

Solution 3:[3]

NZTony's answer in VB.net:

Public Sub test()
        Dim smtpAddress As String
        Dim selectedItem As Outlook.Folder
        smtpAddress = ""
        TryGetSmtpAddress(Application.ActiveExplorer.Selection.Item(1).Parent, smtpAddress)
End Sub

Public Shared Function TryGetSmtpAddress(ByVal folder As MAPIFolder, ByRef smtpAddress As String) As Boolean
        smtpAddress = "default"
        Dim storeId = HexToBytes(folder.StoreID)

        If BitConverter.ToUInt64(storeId, 4) <> &H1A10E50510BBA138UL OrElse BitConverter.ToUInt64(storeId, 12) <> &HC2562A2B0008BBA1UL Then
            Return False
        End If

        Dim indexDn = Array.IndexOf(storeId, CByte(&H0), 60) + 1
        Dim indexV3Block = Array.IndexOf(storeId, CByte(&H0), indexDn) + 1

        If BitConverter.ToUInt32(storeId, indexV3Block) <> &HF43246E9UL Then
            Return False
        End If

        Dim offsetSmtpAddress = BitConverter.ToUInt32(storeId, indexV3Block + 12)
        smtpAddress = BytesToUnicode(storeId, indexV3Block + CInt(offsetSmtpAddress))
        Return True
End Function

    Private Shared Function HexToBytes(ByVal input As String) As Byte()
        Dim bytesLength = input.Length / 2
        Dim bytes = New Byte(bytesLength - 1) {}

        For i = 0 To bytesLength - 1
            bytes(i) = Convert.ToByte(input.Substring(i * 2, 2), 16)
        Next

        Return bytes
End Function

    Private Shared Function BytesToUnicode(ByVal value As Byte(), ByVal startIndex As Integer) As String
        Dim charsLength = (value.Length - startIndex) / 2
        Dim chars = New Char(charsLength - 1) {}

        For i = 0 To charsLength - 1
            Dim c = CSharpImpl.__Assign(chars(i), BitConverter.ToChar(value, startIndex + i * 2))
            If c = vbNullChar Then
                Return New String(chars, 0, i)
            End If
        Next

        Return New String(chars)
End Function

Private Class CSharpImpl
        <Obsolete("Please refactor calling code to use normal Visual Basic assignment")>
        Shared Function __Assign(Of T)(ByRef target As T, value As T) As T
            target = value
            Return value
        End Function
End Class

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Community
Solution 3 EƱaut