这里的问题是 MyGroups 属性被标记为 NotScriptable,这意味着您不能以您正在使用的方式调用它,即使用 AutomationFactory。出于安全原因,自动化 API 中的某些属性和方法不可编写脚本 - 这是为了避免恶意页面使 Communicator 自动化并在您不知情的情况下执行某些任务。
看起来 Silverlight 中的 COM 互操作的处理方式与从 VBScript 创建和调用 API 的方式相同,因此您将无法访问任何不可编写脚本的属性和方法。有关哪些属性和方法不可编写脚本的详细信息,请参阅参考资料。
我猜这会严重阻碍您的应用程序。我认为伤害你的是选择 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)