How to integrate IM application with Office without Lync installed?

I am trying to integrate an IM application with Office 2019 where Lync/Skype for Business is not installed. The official Microsoft doc says :
If you are integrating using Office Standard, you need to extract the type library and install it on the target machine.
Following this, I have extracted the Unified Collaboration API 1.0 Type Library
using OLE/COM Object Viewer. Then I compiled the IDL file using MIDL compiler and created a TLB file. Then I created an assembly called UCCollaborationLib.dll
using tlbimp
and referenced this dll inside the IM client application to implement all the required interfaces like IUCOfficeIntegration
.
When Lync/Skype for Business is installed, the integration works. When Outlook starts, it looks for the keys from the registry and calls the GetAuthenticationInfo
method of the IUCOfficeIntegration
interface which is implemented by our class PresenceProvider
.
After uninstalling Lync/Skype for Business, the type library Unified Collaboration API 1.0 Type Library
is unregistered along with it.
When the IM application starts, it registers the tlb file using OleAut32.LoadTypeLibEx
. After this, the type library is visible in the OLE/COM Object Viewer but now it is referencing our tlb file instead of lync.exe
which was being referenced earlier when Lync/Skype for Business was installed.
Now when Outlook starts, it is fetching the keys from the registry(observed through Procmon) but it is not calling the GetAuthenticationInfo
method.
Does anybody know what can we do to debug and solve this issue?
If the COM object was not properly handling the QI, then it would not work even when Lync/Skype for Business is installed, but it is working in that case. So I guess it is being properly handled. Also, which debugger are you talking about? How can I debug this process?
Visual Studio debugger or WinDbg. You should be able to attach the debugger to your IM client process after it has started.
Presumably after installing Lync/Skype for Business you have to change registry keys so that Office finds your IM client. After uninstalling Lync/Skype for Business have you gone back through the registry to confirm that the requred keys/values are still present and set for your IM client?
Yes, I have confirmed the values in the registry and the required keys/values are present in the registry.
After attaching the debugger, I saw that the flow until the
CreateInstance
function of theIClassFactory
is the same. After that, theGetAuthenticationInfo
method is called when Lync/Skype is installed and it's not called when Lync is uninstalled.I am using this sample code which I found here.
I believe you have a marshaling problem. If the marshaling information for the IUCOfficeIntegration interface is not present in the registry then an attempt to instantiate your PresenceProvider COM object and return the IUCOfficeIntegration interface will fail with E_NOINTERFACE which is what was returned to a minimal C++ COM client. Then, I ran your CSExeComServerTest.exe application and instantiated your COM object while requesting that it return IDispatch instead of IUCOfficeIntegration. The COM object was instantiated and I was able to call the GetAuthenticationInfo method using IDispatch::Invoke.
You need to check the Interface key of the registry to see if it contains the IUCOfficeIntegration interface.
Using IUCOfficeIntegration -
Using IDispatch -
I checked the interface key of the registry and the interface
IUCOfficeIntegration
is not being registered when Lync is not installed. I checked in OLEViewer and the interface is present in the type library that we are registering and I can find the typelib in the registry. So why aren't the interfaces being registered? Do we have to do something separately to register the interfaces?Also, while you are testing this, do you have Lync/Skype for Business installed in your system?
No, I don't have Lync/Skype for Business installed on my system.
There is nothing in the OLPresenceProvider sample solution that registers a type library.
That is just the sample code that I used. I am attaching my project with this comment. In the DLL directory, there are three IDLs and TLBs that I am registering through the code in
CSExeCOMServerTest/Program.cs
. When we runCSExeCOMServerTest.exe
, the type libraries get registered and those keys are made in the registry which are required by Outlook to look for IM Providers.OLPresenceProvider.zip
Sign in to comment
I observed two issues with respect to the new OLPresenceProvider sample solution.
The code is attempting to register type libraries per-machine (HKLM). Per-machine registration requires that the code is running with elevated privileges. I would expect the sample code to return a COM error (hr < 0) but it does not. I don't know why but I have made a change in the type library registration function that properly indicates failure when an un-elevated process attempts per-machine registration.
After implementing this change and running the COM Server with elevated privileges type library registration succeeded for interopExtension.tlb and lyncEndorser.tlb. However, registration failed for lync.tlb and this is the reason why the IUCOfficeIntegration interface is not in the registry.
It is my belief that something is wrong with the lync.tlb type library created from the IDL shown by OleView when browsing the real type library. See if you can extract the lync type library as a binary file from the Office executable.
Register a type library -
Add to Ole32 class -
I experimented by changing the type library registration code to per-user instead of per-machine. See RegisterTypeLibForUser and UnRegisterTypeLibForUser. After making this change and running the COM Server un-elevated all type libraries were successfully registered and the minimal C++ COM client was able to instantiate the COM object and obtain the IUCOfficeIntegration interface.
Just a thought -- When you install Lync/Skype for Business is the type library containing IUCOfficeIntegration registered per-machine or per-user?
It is registered per-machine. @RLWA32
Have you tried my suggested change for per-machine registration? If you did, did it fail with error code TYPE_E_REGISTRYACCESS (0x8002801C) for lync.tlb?
If you cannot register lync.tlb per-machine (and don't want to register per-user) there are a couple of workarounds I can help you with if you are interested.
Using the
RegisterTypeLibForUser
function, I was able to successfully register the type library along with all the interfaces. As a result, Outlook is now calling theGetAuthenticationInfo
method.I tried your change for the per-machine registration but it failed with an error. So to fix the tlb, I extracted the tlb from
lync.exe
and used theRegisterTypeLib
method instead ofRegisterTypeLibForUser
and it didn't fail. But on looking through the registry, I see only the typelib registration inHKEY_LOCAL_MACHINE
. No interfaces are registered per-machine.Well, I am happy with the per-user registration but I am also interested in knowing those workarounds for the per-machine registration.
Also, I want to thank you for all the help you have provided so far.
Well, the workaround idea is to use RegOverridePredefKey to capture the type library registration to a user defined key in HKCU. Once that is accomplished, you could export the information to a .reg file. Then, you could edit the .reg file to refer to the proper registry locations for per-machine registration for subsequent import or write the information to the registry using your own code. There would be details to consider (e.g., 64-bit vs 32-bit) but that's the basic idea.
If you can go with per-user registration its probably not worth the effort. :)
Yes, you're right. I can go with the per-user registration so it's not worth the effort.
BTW, can you share the code for the C++ client that you were using to test the COM server?
Sign in to comment
1 additional answer
Sort by: Most helpful
Following is the minimal C++ client code. I had to post it as an Answer due to the 1600 character limit for comments.
Thank you so much. :)
Sign in to comment
Activity