'Search Outlook Global Address List Asynchronously
I want to;
- Search the Global Address List of MS Outlook
- Using an input, filterStr
- To retrieve all items asynchronously that match a criteria satisfying
- Contact first name starts with filterStr or contact last name starts with filterStr
- Display the contacts as they become available in some sort of list
I am developing a MS Outlook add-in with Visual Studio 2017 using VB.net. (c# code examples are wellcome). I need this add-in to be able to search contacts like MS Skype for Business does, through its "Find Someone" field of "RICHEDIT60W"
I have tried the following so far;
- Use "RICHEDIT60W" of MS Skype for Business (the search field) in my form
- Could not find documentation
- Use the "RichEdit20WPT" of MS Outlook (the "TO:" field in new e-mail compose)
- Could not find documentation
- Get the "Global Address List" through
Session.GetGlobalAddressList
- Succeeded, but looping through more than 50k items is too slow
- Use the
System.DirectorySearcher
- This does not always work. When I'm connected to my corporate network through cable, I can create the object. When I'm connected through my home wireless, I get the error: "specified domain does not exist or could not be contacted"
- I did try using a
DirectoryEntry
object initialized with; name.surname.corporation.com
where my e-mail address is [email protected], this time I get an "unspecified error"- I tried using ADODB to connect as given in https://docs.microsoft.com/en-us/windows/desktop/ad/example-code-for-searching-for-users#visual-basic-example
- This also gives me an error on line 42 (
root = GetObject("LDAP://rootDSE"
)
QUESTION: How can I do any of the following;
- Get
DirectorySearcher
to work - Get ADODB method to work
- Use the existing RichEdit controls of either Outlook or Skype for Business
?
Solution 1:[1]
I solved it like this;
- Getting the GAL itself and the
AddressEntries
is fast enough, no problem there - I'm looping through the
AddressEntries
only once, during initialization and getting only theName
properties of each to aList(Of String)
, which takes around 3 seconds - When I need to search for an entry, I'm using Linq to query the list with
IndexOf
function, which takes about 150ms max to get all matches, and the items of the list are immediately accessible
This suited my needs because - It works through my home network and even when I don't have a connection (I assume Outlook is cacheing the GAL) - Querying using Linq is fast enough to facilitate searching as the user types
Solution 2:[2]
On the low (Extended MAPI - C++ or Delphi only) level, you would need to apply PR_ANR
MAPI restriction: that is what Outlook uses when it resolves a name and displays the list of ambiguous matches. You can run that code on a separate thread, but it won't return matches one at a time - you will get the whole set back.
If Extended MAPI is not an option, you can use Redemption (I am its author) and its RDOSession.AddressBook
.GAL.ResolveNamesEx method:
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set AdrrEntries = Session.AddressBook.GAL.ResolveNameEx("John")
Debug.Print AdrrEntries.Count & " names were returned by ResolveNameEx:"
Debug.Print "------------"
for each AE in AdrrEntries
Debug.Print AE.Name
next
Debug.Print "------------"
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 | Teeracroptus |
Solution 2 |