这里的问题是 MyGroups 属性被标记为 NotScriptable,这意味着您无法以您正在执行的方式(即使用 AutomationFactory)调用它。出于安全原因,自动化 API 中的某些属性和方法不可编写脚本 - 这是为了避免恶意页面在您不知情的情况下自动执行 Communicator 并执行某些任务。
看起来 Silverlight 中的 COM 互操作的处理方式与例如相同。从 VBScript 创建和调用 API,因此您将无法访问任何不可编写脚本的属性和方法。请参阅参考 http://msdn.microsoft.com/en-us/library/bb758755%28office.12%29.aspx了解哪些属性和方法不可编写脚本的详细信息。
我猜这会严重阻碍您的应用程序。我认为对您造成伤害的是选择 Silverlight OOB 的决定。有没有什么方法可以使用 WPF(甚至 winforms)而不是 Silverlight?如果您这样做,您可以直接引用 API,并拥有对所有属性/方法的完全访问权限。
不然我也想不出太多的选择。你无法捕获OnContactAddedToGroup
事件,因为它不可订阅。
It might可以用 .NET 程序集包装 API,并通过 COM 公开它,然后以相同的方式实例化它 - 但在这种情况下,“不可编写脚本”可能仍然受到尊重,因此它不会为您购买任何东西。不尝试就很难说,但这仍然是一个相当糟糕的解决方案。
Edit:我刚刚尝试了包装器方法(需要为客户做类似的概念验证),它似乎有效。我就是这样做的:
创建一个新的.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 http://msdn.microsoft.com/en-us/library/tzat5yw6%28VS.71%29.aspx。然后从 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)