我正在开发一个浏览器外的Silverlight应用程序,它提供了一些MS Office Communicator 2007控件。我在用Automation 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接口中的属性?我在网上看到了一些东西,说Windows Messenger不推荐使用MyGroups,但从文档中看,它似乎应该适用于MS Office Communicator。
如果我不能使用MyGroups,有没有其他方法可以获取用户创建的组?
发布于 2010-12-02 01:29:11
这里的问题是MyGroups属性被标记为NotScriptable,这意味着您不能像使用AutomationFactory那样调用它。出于安全原因,Automation API中的某些属性和方法是不可脚本化的-这是为了避免恶意页面在您不知情的情况下自动执行Communicator和执行某些任务。
看起来Silverlight中的COM互操作与从VBScript创建和调用应用程序接口的方式是一样的,因此您将无法访问任何非脚本化的属性和方法。有关哪些属性和方法不可脚本化的详细信息,请参阅reference。
我猜这会严重阻碍你的应用。我认为伤害你的是使用Silverlight OOB的决定。有没有办法使用WPF (甚至winforms)而不是Silverlight?如果您这样做了,您可以直接引用API,并拥有对所有属性/方法的完全访问权限。
否则,我想不出太多的选择。您不能捕获OnContactAddedToGroup事件,因为这不是可脚本化的。
可以使用.NET程序集包装应用程序接口,并通过COM公开它,然后以同样的方式实例化它-但在这种情况下,可能仍然会考虑不可脚本化,因此它不会给您带来任何好处。不尝试就很难说,而且仍然是一个相当糟糕的解决方案。
编辑:我刚刚尝试了一下包装器方法(需要为客户做一些类似于概念验证的事情),而且它似乎起作用了。我就是这样做的:
创建新的.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)
https://stackoverflow.com/questions/4325808
复制相似问题