MyGroups未在Communicator.UIAutomation中实现

时间:2010-12-01 15:16:31

标签: silverlight com office-communicator

我正在开发一个浏览器Silverlight应用程序,它提供了一些MS Office Communicator 2007控件。我正在使用Automation SDK。随SDK一起安装的文档声明IMessenger2接口中存在MyGroups属性,该属性将返回用户已定义的组,但是当我尝试使用它时,我得到NotImplementedException。这是我正在使用的代码:

dynamic communicator = AutomationFactory.CreateObject("Communicator.UIAutomation");
communicator.AutoSignin();
foreach (dynamic g in communicator.MyGroups)
{
    //Do something with the group
}

如果我用MyContacts替换MyGroups,我可以很好地获取联系人列表。我是否必须做一些不同的事情来访问IMessenger2界面中的属性?我在网上看到一些事情表明MyGroups已被弃用于Windows Messenger,但是从文档来看,它似乎应该可用于MS Office Communicator。

如果我不能使用MyGroups,是否有其他方法可以获取用户创建的组?

1 个答案:

答案 0 :(得分:0)

这里的问题是MyGroups属性被标记为NotScriptable,这意味着你不能以你正在使用的方式调用它,即使用AutomationFactory。出于安全原因,Automation API中的某些属性和方法不可编写脚本 - 这是为了避免恶意页面自动执行Communicator并在您不知情的情况下执行某些任务。

看起来Silverlight中的COM互操作的处理方式与例如从VBScript创建和调用API,因此您将无法访问任何不可编写脚本的属性和方法。有关哪些属性和方法不可编写脚本的详细信息,请参阅reference

我猜这会严重妨碍你的应用。我认为伤害你的是决定使用Silverlight OOB。你有没有办法使用WPF(甚至是winforms)而不是Silverlight?如果您这样做,您可以直接引用API,并拥有对所有属性/方法的完全访问权限。

否则,我想不出太多选择。您无法捕获OnContactAddedToGroup事件,因为这不是可编写脚本的。

可能可以使用.NET程序集包装API,并通过COM公开它,然后以相同的方式实例化它 - 但在这种情况下,Not Scriptable可能仍然受到尊重,所以它不会给你买任何东西。很难说没有尝试,仍然是一个相当可怕的解决方案。

编辑:我刚刚尝试了包装器方法(需要做一些类似于客户的概念验证),它似乎有效。这就是我这样做的方式:

创建一个新的.NET类库。定义COM接口:

[ComVisible(true)]
[Guid("8999F93E-52F6-4E29-BA64-0ADC22A1FB11")]
public interface IComm
{
    string GetMyGroups();
}

定义一个实现该接口的类(您需要从SDK引用CommunicatorAPI.dll):

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[GuidAttribute("C5C5A1A8-9BFB-4CE5-B42C-4E6688F6840B")]
[ProgId("Test.Comm.1")]
public class Comm : IComm
{
    public string GetMyGroups()
    {
        var comm = new CommunicatorAPI.MessengerClass();

        var groups = comm.MyGroups as IMessengerGroups;
        return string.Join(", ", groups.OfType<IMessengerGroup>().Select(g => g.Name).ToArray());
    }
}

构建,并使用RegAsm注册。然后从OOB silverlight应用程序调用:

dynamic communicator = AutomationFactory.CreateObject("Test.Comm.1");
MessageBox.Show(communicator.GetMyGroups());

注意,使用Lync API也可以使用相同的技术:

public string GetMyGroups()
{
    var comm = LyncClient.GetClient();
    return string.Join(", ", comm.ContactManager.Groups.Select(g => g.Name).ToArray());
}

虽然这有效,但我不能说这是否是一个好习惯,因为它正在解决一个安全限制,这可能是有充分理由的。我想最糟糕的情况是恶意网页可能会使用该组件,如果它知道控件的ProgId。

编辑:另外,使用这种方法你需要注意内存泄漏,例如:确保你在完成它们时释放COM对象 - 很容易做到,只需要一点点训练; o)