0

Trying to set the active Lync Audio device to one of the available audio devices. Lync_Client.DeviceManager.AudioDevices.Count returns a number greater than 0 but statements like Lync_CLient.DeviceManager.AudioDevices[i] in a for loop from i = 0 to i < count or foreach (AudioDevice dev in Lync_Client.DeviceManager.AudioDevices) immediately raises an exception when run on Windows 10 PC - but not on Windows 7 PC. Windows 10 version produces an exception with the Message: "Exception has been thrown by the target of an invocation.

Any suggestions? Could this be a privilege issue?

Below is the StackTrace:

...at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
...at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
...at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
...at Microsoft.Lync.Model.Internal.UCWCache.CreateUCW(Object source, CCOMInfo ccomInfo)
...at Microsoft.Lync.Model.Internal.UCWCache.GetITTargetNS(Object source)
...at Microsoft.Lync.Model.Internal.UCEnumerator`2.get_Current()
...at ...Microsoft.Lync.Model.Internal.UCEnumerator`2.System.Collections.Generic.IEnumerator<S>.get_Current()

The stack from here on out points to my code that attempts to access the Lync AudioDevices elements enumeration

Graham
  • 7,431
  • 18
  • 59
  • 84
T Moran
  • 13
  • 5

1 Answers1

0

The problem is that Microsoft stop releasing the Lync Client SDK for Lync 2013 Client. Even though the SDK still works so the latest version of the Skype for Business Client, it is actually slowly breaking due to incompatibilities between the current Skype for Business client and the older Lync Client SDK.

The AudioDevice area of the SDK is a one of the known areas of the SDK where the Client SDK is breaking. There is a workaround where you can drop down to the actual the raw COM interfaces that the Lync Client SDK uses and then use those COM objects directly get access to the API.

You can escape the Lync Client SDK into the raw COM objects by accessing the "InnerObject" field of the Lync Client SDK object.

eg:

    static bool SetClientAudioDevice(LyncClient client, string name)
    {
        var innerClient = (ILyncClient)client.InnerObject;
        var deviceManager = innerClient.DeviceManager;

        Console.WriteLine("Current audio device: [{0}]", client.DeviceManager.ActiveAudioDevice.Name);
        Console.WriteLine("Lync Client Audio Devices List:");
        var ok = false;
        foreach (var device in deviceManager.AudioDevices.OfType<Microsoft.Office.Uc.AudioDevice>())
        {
            Console.WriteLine("    AudioDevice: [{0}], Active[{1}], ID[{2}], IsCertified[{3}], Priority[{4}], Type[{5}]", device.Name, device.IsActive, device.Id, device.IsCertified, device.Priority, device.Type);

            if (device.Name.IndexOf(name, StringComparison.InvariantCultureIgnoreCase) >= 0)
            {
                Console.WriteLine("        Setting active device!");
                deviceManager.ActiveAudioDevice = device;
                ok = true;
            }
        }
        return ok;
    }

As pointed out in the comments, you also have to add a reference to "Microsoft.Office.Uc" and also set the Embed InteropType to False.

Shane Powell
  • 13,698
  • 2
  • 49
  • 61
  • Tried this but getting an exception at LyncClient.GetClient. - "Could not load file or assembly 'Microsoft.Office.Uc, Version=15... or one of its dependencies. The system cannot find the file specified. " To compile I had to add a reference to Microsoft.Office.Uc. The path for the DLL points to an instance in Visual Studio 2017. – T Moran Nov 09 '18 at 15:07
  • Conflict between Lync.Model and Office.Uc solved. After "Adding a Reference" to Microsoft.Office.Uc, changed Embed InteropType to False. No longer getting the exception at GetClient and the solution provided by Shane Powell works. – T Moran Nov 12 '18 at 02:37
  • I forgot about the "Embed InteropType", I found the same that you have to set it to false as well. – Shane Powell Nov 12 '18 at 03:14