MyGroups 未在 Communicator.UIAutomation 中实现

发布于 2024-10-05 09:12:20 字数 810 浏览 6 评论 0原文

我正在开发一个浏览器外的 Silverlight 应用程序,它提供了一些 MS Office Communicator 2007 控件。我正在使用 自动化 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,是否有其他方法来获取用户创建的组?

I'm working on a out of browser Silverlight app that provides some MS Office Communicator 2007 controls. I'm using the Automation SDK. The docs that were installed with the SDK state that there's a MyGroups property in the IMessenger2 interface, which will return the groups that a user has defined, but when I try to use it, I get a NotImplementedException. Here's the code that I'm using:

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

If I replace MyGroups with MyContacts, I can get the contact list just fine. Do I have to do something different to access properties in the IMessenger2 interface? I've seen a few things on the web that say that MyGroups was deprecated for Windows Messenger, but from the docs, it seems like it should be available for MS Office Communicator.

If I can't use MyGroups, is there another way to get the groups that a user has created?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦过后 2024-10-12 09:12:20

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

看起来 Silverlight 中的 COM 互操作的处理方式与从 VBScript 创建和调用 API 的方式相同,因此您将无法访问任何不可编写脚本的属性和方法。有关哪些属性和方法不可编写脚本。

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

不然我也想不出太多的选择。您无法捕获 OnContactAddedToGroup 事件,因为该事件不可编写脚本。

也许可以用.NET程序集包装API,并通过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)

The problem here is that the MyGroups property is marked as NotScriptable, meaning you can't call it in the way you are doing i.e. using the AutomationFactory. For security reasons, some properties and methods in the Automation API are not scriptable - this is to avoid malicious pages automating Communicator and carrying out certain tasks without you knowing.

It looks like the COM interop in Silverlight is treated in the same way as e.g. creating and calling the API from VBScript, so you won't be able to access any of the non-scriptable properties and methods. See the reference for details of which properties and methods are not scriptable.

I'm guessing this is going to seriously hobble your app. I think what's hurting you is the decision to go with Silverlight OOB. Is there any way you could use WPF (or even winforms) rather than Silverlight? If you did this, you could reference the API directly, and have full access to all properties/methods.

Otherwise, I can't think of too many options. You can't trap the OnContactAddedToGroup event, as this is not scriptable.

It might be possible to wrap the API with a .NET assembly, and expose it via COM, then instantiate it in the same way - but the Not Scriptable might still be respected in that case, so it won't buy you anything. Hard to say without trying it, and still a fairly horrible solution.

Edit: I've just given the wrapper method a try (needed to do something similar as a proof of concept for a customer), and it seems to work. This is the way I did it:

Create a new .NET class library. Define a COM interface:

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

Define a class that implements that interface (you'll need to reference CommunicatorAPI.dll from the SDK):

[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());
    }
}

Build, and register using RegAsm. Then call from the OOB silverlight app:

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

Note, the same technique also works using the Lync API:

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

Although this works, I can't really say whether it's a good practice, as it's working around a security restriction which was presumably there for a good reason. I guess the worst that could happen is that a malicious web page could potentially use the component, if it knew the ProgId of the control.

Edit: Also, using this method you'd need to be careful about memory leaks, e.g. make sure you're releasing COM objects when you're finished with them - easy enough to do, just needs a little discipline ;o)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文