Get All Contacts using Lync ContactManager
Asked Answered
H

2

6

Right now I'm using the the LyncClient.ContactManager.BeginSearch method to find contacts. However, I haven't been able to figure out how to get all the contacts. I've tried passing "*" and "%" as wild-card characters but that has not worked. Right now here is my function call.

_lyncClient.ContactManager.BeginSearch("*", SearchProviders.GlobalAddressList, SearchFields.DisplayName, SearchOptions.ContactsOnly, 400, SearchCallback, "Searching Contacts");
Hoodlum answered 28/3, 2011 at 13:59 Comment(1)
Here is the link for my forum post on MS regarding the limitations of DistributionGroup size for BeginExpand and BeginGetAllMembers: social.msdn.microsoft.com/Forums/en-US/communicatorsdk/thread/…Hoodlum
L
8

Lync contacts are organised into groups, so you need to start at the Groups level. Once you've got a group, you can then enumerate through it's Contacts

foreach(var group in _client.ContactManager.Groups)
{
    foreach (var contact in group)
    {
        MessageBox.Show(contact.Uri);
    }
}

This article is good for background, and more advanced features

Edit: Specifically, for the distribution groups expansion question, I think the sample here is flawed.

Instead of calling BeginExpand and waiting on the WaitHandle, provide a callback method to handle the Expand callback. So, instead of:

asyncOpResult = DGGroup.BeginExpand(null, null);
asyncOpResult.AsyncWaitHandle.WaitOne();

DGGroup.EndExpand(asyncOpResult);

try this:

...
asyncOpResult = DGGroup.BeginExpand(ExpandCallback, DGGroup);
...

public void ExpandCallback(IAsyncResult ar)
{
    DistributionGroup DGGroup = (DistributionGroup)ar.AsyncState;
    DGGroup.EndExpand(ar);

    etc...
}

This works perfectly for me.

Lingo answered 28/3, 2011 at 15:34 Comment(10)
I used the BeginSearch method to get groups instead and searched for a distribution group with everyone's email address. It returns the correct distribution group but no contacts are returned in the collection.Hoodlum
Have you tried searching using SearchOptions.IncludeContactsWithoutSipOrTelUri, instead of SearchOptions.ContactsOnly?Lingo
IncludeContactsWithoutSipOrTelUri had the same result. I tried to expand the distribution group using the sample on the MS site but it it just hung on asyncOpResult.AsyncWaitHandle.WaitOne() and never finishes (msdn.microsoft.com/en-us/library/gg436849.aspx). The group should have about 200 people but the MS link only says that there should be problems with 1,000+Hoodlum
I edited answer with the solution. Not sure about a UCMA option, but hopefully you won't need to go down that route nowLingo
I used this code but it has only worked on smaller groups. I'm getting an OperationException from the EndExpand Method coming from Microsoft.Lync.Model.Internal.CBWBase.BlockUntilDone(). I tried to use the BeginGetAllMembers method as well and I got the same results. It would work for smaller groups (one with 90 members) but not with the one with about 200. I was also getting the same error. I think maybe it could be related to the MaxSizeGroupSize to expand property here social.technet.microsoft.com/Forums/en-US/ocsclients/thread/…Hoodlum
Sounds like either a bug or a limitation in that call. I'd try and open a support call with MS if you're able toLingo
I'll definitely mark this as the right way to do things though I'm going to use my method till I get a response back from MS.Hoodlum
Cool - let us know if you get a definitive answerLingo
I got a response back from my forum post and it sounds like the SDK is constrained by the limit on the server of 150 users.Hoodlum
Off topic : Is it possible to get the contact ALIAS instead of URI ?Genni
H
1

I ended up doing multiple searches for now to get all the contacts. I go through each letter of the alphabet to find them. The load time is quick enough and I'll just show a loading image on the grid for a little while when it fires up. This worked well for the 200 or so contacts we have though I would recommend Paul's solution for 150 or less. Here is what I did:

private static char[] Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
...

public void GetAllContacts()
{
   int initialLetterIndex = 0;

  _lyncClient.ContactManager.BeginSearch(
    Alphabet[initialLetterIndex].ToString();
    SearchProviders.GlobalAddressList,
    SearchFields.FirstName,
    SearchOptions.ContactsOnly,
    300,
    SearchAllCallback
    new object[] { initialLetterIndex, new List<Contact>() }
  );
}

private void SearchAllCallback(IAsyncResult result)
{
  object[] parameters = (object[])result.AsyncState;
  int letterIndex = (int)parameters[0] + 1;
  List<Contact> contacts = (List<Contact>)parameters[1];

  SearchResults results = _lyncClient.ContactManager.EndSearch(result);
  contacts.AddRange(results.Contacts);

  if (letterIndex < Alphabet.Length)
  {
    _lyncClient.ContactManager.BeginSearch(
      Alphabet[letterIndex].ToString(), 
      SearchAllCallback, 
      new object[] { letterIndex, contacts }
    );
  }
  else
  {
    //Now that we have all the contacts 
    //trigger an event with 'contacts' as the event arguments.
  }
}
Hoodlum answered 29/3, 2011 at 19:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.