Search code examples
c#office-interop

_IContactsAndGroupsCallback.OnLookUp


I'd like to provide IM presence etc for Office, following the guide from http://msdn.microsoft.com/en-US/library/office/jj900715.aspx#off15_IMIntegration_ImplementRequired_ILyncClient.

In response to

IContactManager.Lookup(string _lookupString, object _contactsAndGroupsCallback = null, object _state = Type.Missing)

I need to call

Microsoft.Office.Uc._IContactsAndGroupsCallback.OnLookup(ContactManager _source, object _lookupResult, AsynchronousOperation _asyncOperation);

The second parameter is not well documented:

When Office cannot determine the SIP address for the contact, it calls the IContactManager.Lookup method to find the SIP by using the IM service. Here Office passes in the best data that it can find for the contact (for example, just the email address for the contact). The Lookup method asynchronously returns an AsynchronousOperation object. When it invokes the callback, the Lookup method should return the success or failure of the operation in addition to the URI of the contact.

I tried different passing different results as lookupResult (uri string, .NET Uri object, Contact object) but with no success.

What is the required type of lookupResult?


Solution

  • Finally I could solve it. The parameters are:

    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces(typeof(_IContactManagerEvents))]
    [ComVisible(true)]
    public class MyContactManager : ContactManager
    {
      // Additional implementation details omitted.
    }
    
    
    [ClassInterface(ClassInterfaceType.None)]
    [ComVisible(true)]
    [ComSourceInterfaces(typeof(_IContactEvents))]
    public class MyOfficeContact : Contact 
    {
      // Additional implementation details omitted.
    }
    
    
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class MyAsyncOperation : AsynchronousOperation
    {
      // Additional implementation details omitted.
    }
    

    Hint: When integrating your IM applications with Office, you should implement a simple Office mock and call your own IM application interface. This will help in finding any issues with event handling etc.

    [ComImport, Guid(MyImApp.ClassId)]
    public class MyImApp
    {
      internal const string ClassId = "<your guid>";
    }
    
    public class MyContactAndGroupsCallback : _IContactsAndGroupsCallback
    {
    
      public void OnAddCustomGroup(ContactManager _source, AsynchronousOperation _asyncOperation)
      {
      }
    
      public void OnAddDistributionGroup(ContactManager _source, AsynchronousOperation _asyncOperation)
      {
      }
    
      public void OnLookup(ContactManager _source, object _lookupResult, AsynchronousOperation _asyncOperation)
      {
      }
    
      public void OnRemoveContactFromAllGroups(ContactManager _source, AsynchronousOperation _asyncOperation)
      {
      }
    
      public void OnRemoveGroup(ContactManager _source, AsynchronousOperation _asyncOperation)
      {
      }
    
      public void OnSearch(ContactManager _source, SearchResults _searchResults, AsynchronousOperation _asyncOperation)
      {
      }
    }
    
    class Program
    {
      static bool cancelPressed = false;
      static MyContactAndGroupsCallback myContactsAndGroupsCallback = new MyContactAndGroupsCallback();
    
      static void Main(string[] args)
      {
         MyImApp imApp = new MyImApp();
         if (imApp == null) return;
    
         UCOfficeIntegration officeIntegration = (UCOfficeIntegration)imApp;
         if (officeIntegration == null) return;
    
         officeIntegration.OnShuttingDown += officeIntegration_OnShuttingDown;
    
         string officeVersion = "15.0.0.0";
         string authInfo = officeIntegration.GetAuthenticationInfo(officeVersion);
         OIFeature supportedFeatures = officeIntegration.GetSupportedFeatures(officeVersion); //skype reports: -122
    
         LyncClient lyncClient = (LyncClient)officeIntegration.GetInterface(officeVersion, OIInterface.oiInterfaceILyncClient);
         if (lyncClient == null) return;
    
         string uri = lyncClient.Uri;
    
         IAutomation automation = (IAutomation)officeIntegration.GetInterface(officeVersion, OIInterface.oiInterfaceIAutomation);
    
         //LyncClientCapabilityTypes capabilities = lyncClient.Capabilities; //skype: Not implemented
         lyncClient.OnStateChanged += lyncClient_OnStateChanged;
    
         ContactManager contactManager = lyncClient.ContactManager;
         if (contactManager == null) return;
    
    
         AsynchronousOperation async = contactManager.Lookup("[email protected]", myContactsAndGroupsCallback, Type.Missing);
    
         Contact contact = contactManager.GetContactByUri("[email protected]");
    
         if (contact != null)
         {
            dynamic result = contact.GetContactInformation(ContactInformationType.ucPresenceInstantMessageAddresses);
    
            ContactSettingDictionary settings = contact.Settings;
    
            ContactSetting[] keys = settings.Keys;
    
            if (keys != null)
            {
               foreach (ContactSetting key in keys)
               {
                  object value = null;
                  settings.TryGetValue(key, out value);
               }
            }
    
         }
    
         Console.CancelKeyPress += Console_CancelKeyPress;
    
         Console.WriteLine("Press Ctrl-C for exit");
    
         do
         {
            System.Threading.Thread.Sleep(1000);
    
         } while (!cancelPressed);
    
      }
    
      static void officeIntegration_OnShuttingDown()
      {
         Console.WriteLine("IM Application is shutting down");
      }
    
      static void contactManager_OnSearchProviderStateChanged(ContactManager _eventSource, SearchProviderStateChangedEventData _eventData)
      {
      }
    
      static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
      {
            cancelPressed = true;
         }
    
      static void lyncClient_OnStateChanged(Client _eventSource, ClientStateChangedEventData _eventData)
      {
         Console.WriteLine("Status changed: {0} -> {1}, {2}", _eventData.OldState, _eventData.NewState, _eventData.StatusCode);
      }
    }