Walkthrough: Sign In to Lync with UI Suppressed (Lync 2010 SDK)

This topic shows how to sign a client application in to Microsoft Lync 2010 when the application UI is suppressed. Although in suppression mode, Lync 2010 must be initialized by your custom process.

Lync 2010 operating in the UI Suppression mode is designed to support a single Lync 2010 API enabled process at a time. You should examine the Lync 2010 state before initializing it. If the state is already initialized and your custom process did not initialize Lync 2010, then you should not continue with the initialization and sign-in process.

Hh378603.OCOM_SignIn_NotInitialized(en-us,office.14).png

Prerequisites

Important

Before starting this walkthrough, complete the following tasks.

To Initialize the Client

  1. Get the LyncClient instance. The Microsoft.Lync.Model namespace exposes the LyncClient class. You call the static GetClient method on that class to obtain an instance of LyncClient.

  2. Register for the StateChanged and CredentialRequested events for this LyncClient instance.

    Tip

    LyncClient is derived from Client, which means the StateChanged event can be registered by using LyncClient.

  3. Get the UI suppression state of the client by reading the InSuppressedMode property.

    If the property value is true, you must initialize the client.

  4. Get the current client state and call into BeginInitialize if the client state is ClientState.Uninitialized.

    Important

    If the client state is not ClientState.Uninitialized then a different process has already initialized Lync 2010. Custom applications that are designed to have exclusive use of Lync 2010 should exit at this point.

  5. In the initialization callback method that you defined, read the System.IAsyncResult.IsComplete property.

    If the value of the property is true then the initialize operation is is completed.

    Tip

    You should set an application flag here to keep track of the fact that your application initialized Lync 2010. Your sign out/shut down logic must be able to determine whether Lync 2010 was initialized by the current process. If your current process did not initialize Lync 2010, it must not attempt to shut Lync 2010 down.

  6. Handle the client state changed event.

    If the new client state is ClientState.SignedOut, Call the BeginSignIn method. When UI Suppression is enabled, the user credential parameters should not be null . When required credentials are not passed in the sign in method, the operation raises the CredentialRequested event. You call Submit, passing user credentials in the first two arguments of the method. The sign-in process is completed when acceptable credentials have been submitted.

    You can pass a callback delegate and a state object. If you do not pass a callback delegate to BeginSignIn, you must pass a null value in its position. It is very important that you do not ignore the return value (System.IAsyncResult) if you intend to call EndSignIn on your UI thread instead of inside a callback passed into BeginSignIn. For more information about callback delegates, see Lync Asynchronous Programming (Lync 2010 SDK).

  7. Handle the CredentialRequested event by collecting the user’s credentials and supplying them to the client.

    This event is raised when you have called BeginSignIn with null values in the first three arguments.

  8. Handle the client state changed event.

    If the new client state is ClientState.SigningIn, Lync 2010 is completing the user sign-in process. You may experience a delay of several seconds depending on the current level of network traffic.

    When the user is signed in, you receive a client state changed event indicating the current client state is ClientState.SignedIn.

Examples

The following examples initialize and sign a user in to a Lync 2010 instance that runs with a suppressed UI.

Initialize Callback Method

The following example is invoked by the client when the initialize operation is is completed.

        /// <summary>
        /// callback method called by LyncClient.SignIn()
        /// </summary>
        /// <param name="source">LyncClient</param>
        /// <param name="_asyncOperation">IAsynchronousOperation callback</param>
        /// 
        private void SigninCallback(IAsyncResult ar)
        {
            if (ar.IsCompleted == true)
            {
                try
                {
                    ((LyncClient)ar.AsyncState).EndSignIn(ar);
                }
                catch (RequestCanceledException re)
                {
                    MessageBox.Show("Request canceled exception: " + re.Message);
                }
            }
            
        }
        /// <summary>
        /// Handles the asynchronous initialize callback invoked by a client instance upon initialize
        /// </summary>
        /// <param name="initializedClient">LyncClient. The initialized client.</param>
        /// <param name="AsyncOp">IAsynchronousOperation. The async interface exposing the results of the operation.</param>
        private void InitializeCallback(IAsyncResult ar)
        {
            if (ar.IsCompleted == true)
            {
                object[] asyncState = (object[])ar.AsyncState;
                ((LyncClient)asyncState[0]).EndInitialize(ar);

                //_ThisInitializedLync is part of application state and is 
                //a class Boolean field that is set to true if this process
                //initialized Lync.
                _ThisInitializedLync = true;
            }
        }

ClientStateChanged Event Handler

        /// <summary>
        /// Handles LyncClient state change events. 
        /// </summary>
        /// <param name="source">Client.  Instance of LyncClient as source of events.</param>
        /// <param name="data">ClientStateChangedEventArgs. State change data.</param>
        void _Client_ClientStateChanged(Object source, ClientStateChangedEventArgs data)
        {
            if (ClientStateChangedEvent != null)
            {
                if (data.NewState == ClientState.SignedIn)
                {
                    MessageBox.Show(“Signed in”);
                }
                if (data.NewState == ClientState.SignedOut)
                {
                    ((LyncClient)source).BeginSignIn(null, null, null, SigninCallback, source);
                }
            }
        }

Credentials Request Event Handler

The following example obtains the local users credentials and passes them to the client.

        void _LyncClient_CredentialRequested(object sender, CredentialRequestedEventArgs e)
        {
            if (e.Type == CredentialRequestedType.SignIn)
            {
                e.Submit("FranckH@contoso.com", "Frank_Password", false);
            }
        }

Initialize the Client

The following example registers for state change events on the client, checks the current state of the client, and initializes the client if it is not initialized.

The code in this example is appropriate for applications designed to have exclusive access to Lync 2010.

        /// <summary>
        /// Custom application class constructor. This class wraps the functionality of UCClient
        /// </summary>
        public ClientModel()
        {
            try
            {

                _LyncClient = LyncClient.GetClient();
                if (_LyncClient == null)
                {
                    throw new Exception("Unable to obtain client interface");
                }
                if (_LyncClient.InSuppressedMode == true)
                {
                    if (_LyncClient.State == ClientState.Uninitialized)
                    {
                        Object[] _asyncState = { _LyncClient };
                        _LyncClient.BeginInitialize(InitializeCallback, _asyncState);
                    }
                }
                _LyncClient.SignInDelayed += _LyncClient_SignInDelay;
                _LyncClient.StateChanged += _Client_ClientStateChanged;
                _LyncClient.CredentialRequested += new EventHandler<CredentialRequestedEventArgs>(_LyncClient_CredentialRequested);
            }
            catch (NotStartedByUserException h)
            {
                throw new ClientWrapException(h, "Lync is not running", true);
            }
            catch (Exception ex)
            {
                throw new ClientWrapException(ex, "General Exception", true);
            }
        }

Next Steps

Your client is now in a state where you can use all Lync 2010 API functionality. You can obtain the users contacts, start and accept conversations, and complete user sign-out process.

See Also

Concepts

Lync Model API Concepts (Lync 2010 SDK)

Writing Lync 2010 SDK Applications