有没有办法获得mapidolder或outlook interop文件夹的smtpaddress给定entryid(或storeid)

时间:2014-01-29 22:01:42

标签: outlook

如果我有一个mapidolder的storeid,通过outlook interop库中的folderpicker选择,有没有办法让我获得该文件夹的smtpaddress?

我知道它在扩展属性中,但我希望在没有任何繁重的解析或ldap查询的情况下完成它。

我需要smtpaddress的原因是为了通过EWS连接到文件夹 - 我目前正在尝试用交换Web服务替换我们对outlook interop的引用,这已成为一个棘手的问题,因为我们的许多用户拥有对不属于他们的邮箱的委托访问权

3 个答案:

答案 0 :(得分:2)

对于邮箱所有者,您可以尝试读取MAPIFolder.Store属性以访问父存储,然后使用Store.PropertyAccessor.GetProperty读取PR_MAILBOX_OWNER_ENTRYID属性(DASL名称"http://schemas.microsoft.com/mapi/proptag/0x661B0102")。然后,您可以使用商店所有者条目ID来调用Namespace.GetAddressEntryFromID。获得AddressEntry对象后,可以使用AddressEntry.GetExchangeUser.PrimarySmtpAddress。

请注意,PR_MAILBOX_OWNER_ENTRYID属性仅适用于在线商店。您可能希望使用Redemption及其RDOExchangeMailboxStore。Owner.SmtpAddress属性。可以使用RDOSession.GetRDOObjectfromOutlookObject(Store)或使用RDOSession.GetStoreFromID检索RDOExchangeMailboxStore。

答案 1 :(得分:1)

我知道已经多年了(很抱歉),但是我需要获取一堆邮箱的smtp地址,并且无法接受的答案不起作用(因为我有离线商店),所以我进行了解析... < / p>

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);
}

答案 2 :(得分:0)

NZTony在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