我正在开发一个浏览器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,是否有其他方法可以获取用户创建的组?
答案 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)