通过调用LyncClient.GetClient()获取无效对象

时间:2015-06-05 13:02:10

标签: c# lync-2013 lync-client-sdk

注意:更新了问题底部的解决方案

我在使用Lync 2013 SDK的应用程序时遇到了一些问题。以下是我看到的行为:

  • 如果在启动应用程序时Lync已在运行,则对LyncClient.GetClient()的调用将返回有效的客户端对象。
  • 如果在我启动应用程序时Lync未运行,则对LyncClient.GetClient()的调用将抛出ClientNotFoundException。我可以处理异常并启动一个计时器来ping客户端。稍后,当我启动Lync时,LyncClient.GetClient()将返回一个有效的客户端对象。
  • 如果Lync在我的应用程序运行时退出,那么我可以通过多种方式检测到这种情况并启动计时器以ping客户端以便返回。

到目前为止一切顺利,但问题出在哪里:

  • 如果Lync在我的应用程序运行时消失,那么后续对LyncClient.GetClient()的调用似乎返回一个有效的客户端对象(即使Lync没有运行),但尝试调用此对象会抛出{{1} }。
  • 即使在重新启动Lync之后,当我尝试访问它时,对InvalidCastException的后续调用仍然会返回一个抛出LyncClient.GetClient()的对象。

例外的细节是:

  

无法转换类型为' System .__ ComObject'的COM对象。到界面类型' Microsoft.Office.Uc.IClient'。此操作失败,因为QueryInterface调用COM组件上的接口与IID' {EE9F3E74-AC61-469E-80D6-E22BF4EEFF5C}'由于以下错误而失败:RPC服务器不可用。 (来自HRESULT的异常:0x800706BA)。

我在这里尝试了推荐:Troubleshooting Lync 2013 SDK development issues。它似乎没有任何区别。在Lync运行并再次登录后,我会在几分钟内继续获取无效的客户端对象。

每次都不会发生这种情况。如果Lync在我的应用程序启动时已经运行(即第一次调用InvalidCastException成功),问题似乎一直发生。另一方面,如果我启动Lync,一切似乎在多次重启Lync时都能正常工作在我的应用程序已经运行之后(即第一次尝试LyncClient.GetClient()失败。)

之前有其他人见过吗?有什么建议吗?

尝试卸载AppDomain

进行更新

我尝试使用此代码获取客户端对象,但行为完全相同:

GetClient()

使用专用线程的解决方案示例

感谢 djp 的输入,我实现了这个简单的类来提供public class LyncClientProvider { private AppDomain _domain = CreateDomain(); public LyncClient GetLyncClient() { if (_domain == null) CreateDomain(); var client = GetClient(); if (client != null && client.Capabilities != LyncClientCapabilityTypes.Invalid) return client; // Reload AppDomain if (_domain != null) AppDomain.Unload(_domain); _domain = CreateDomain(); return GetClient(); } private LyncClient GetClient() { if (_domain == null) return null; return ((InternalProvider) _domain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof (InternalProvider).FullName)).GetLyncClient(); } private static AppDomain CreateDomain() { return AppDomain.CreateDomain("LyncClientCreator", null, new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.BaseDirectory, ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile }); } [Serializable] private class InternalProvider { public LyncClient GetLyncClient() { try { return LyncClient.GetClient(); } catch (Exception) { return null; } } } } ,重新连接现在正常工作。

LyncClient

3 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,我的修复方法是确保每次调用LyncClient.GetClient()都发生在同一个帖子上

答案 1 :(得分:0)

“•如果Lync在我的应用程序运行时消失,那么后续对LyncClient.GetClient()的调用似乎返回一个有效的客户端对象(即使Lync没有运行),但尝试调用此对象会抛出InvalidCastException。 “

你能详细说明你的意思吗?“如果Lync消失了”。您是说您已退出Lync还是已退出Lync(即没有运行Lync进程)?如果您刚刚退出Lync LyncClient,则不会抛出异常。您可以收听LyncClient.StateChanged事件并检查clientStateChangedEventArgs.NewState事件。

private void LyncClient_StateChanged(object sender, ClientStateChangedEventArgs e) {
        switch (e.NewState) {
                case ClientState.Invalid:
                case ClientState.ShuttingDown:                  
                    this.IsLyncStarted = false;
                    this.IsLyncSignedIn = false;
                    break;
                case ClientState.SignedOut:
                case ClientState.SigningIn:
                case ClientState.SigningOut  
                    this.IsLyncStarted = true;
                    this.IsLyncSignedIn = false;
                    break;
                case ClientState.SignedIn:
                    this.IsLyncStarted = true;
                    this.IsLyncSignedIn = true;
                    break;
            }
            if (!this.IsLyncStarted || !this.IsLyncSignedIn) {                    
                // Do relevant operation
                // Show error message to user - Lync is not present
            }
    }

当用户退出Lync时 - 我启动类似于您的方法的计时器并尝试初始化Lync,如下所示:

private void InitializeLync() {
        try {
            if (this.LyncClient == null || this.LyncClient.State == ClientState.Invalid) {
                this.LyncClient = LyncClient.GetClient();

                if (this.LyncClient != null) {
                    this.LyncClient.StateChanged += this.LyncClient_StateChanged;       
                }
            }

        } catch (Exception ex) {
            // Show message to user that Lync is not started
        }
}

这对我有用。可能是机器特定的问题。

答案 2 :(得分:-2)

我假设您正在与Lync服务器断开连接。 LyncClient.GetClient()方法可能仍然有效,因为您有一些延迟变量,但您无法使用它预先形成任何Lync操作。

我认为查看UI抑制功能会有所帮助。 https://msdn.microsoft.com/en-us/library/office/hh345230%28v=office.14%29.aspx