2011-05-13 25 views
3

我正在写一个COM组件作为IE中的一个工具栏,它有一个有趣的问题。基本上,如果您在IE中一次打开多个选项卡,则COM对象的各个实例都会扭曲。在这里忍受我。在IE工具栏中对实例的静态引用

假设我通过右键单击几个不同的链接并在新选项卡中打开它们,一次打开五个浏览器选项卡。现在,我的工具栏的功能包括选择网页中的文本,然后单击按钮将该文本复制到工具栏中。所以让我们在标签3中做到这一点。我们选择文本并单击按钮,但没有任何内容。但是,如果我们选择标签2中的文本,然后回到标签3并单击按钮,我们将在标签2中选择文本。所以...标签3中的工具栏从标签中获取东西2.不好。

我已经将这个问题追溯到我们的COM对象,工具栏中的静态引用。

[ComVisible(true), Guid("2CC75392-1182-470D-BECC-EFA33E629AB8")] 
[CLSCompliant(false)] 
public sealed class Toolbar : ADXIEToolbar 
{ 

    public static Toolbar Instance; 

    public Toolbar() 
    { 
     Instance = this; 

     InitializeComponent(); 

    } 

    ...other code... 
} 

注意每个IE标签只存在一个工具栏实例。

此引用没有得到正确的分配,几乎就像它不是线程安全的(它不是),而是不是域安全的或其他东西。它有时会引用另一个实例。与其他静态字段,甚至线程安全单例相同。我不明白。

另请注意,如果我将此工具栏(在InitializeComponent内)的引用传递给控件,​​我有同样的问题。

this.publicationDateCb.Toolbar = this; 

此引用有时会指向不同的选项卡。

如果我使用一个纯粹的基于订阅的模型和绝对为零的静态引用,工具栏作为裁判,那么事情似乎很好。这基本上意味着我将不得不将程序重新设计为没有任何类直接相互交互的程序 - 它们触发工具栏订阅的事件,并调用其他类中的方法。哎哟。

所以我应该去那个模型(这可能是理想的,但我在这里很远)还是有我在这里失踪的简单修复?

其他说明:

  • 所有IE选项卡在单独的进程中运行。
  • BHO /工具栏在与IE选项卡相同的过程中运行。
  • 我正在使用Internet Explorer的Add-In-Express来处理IE集成。
  • 该项目是为.NET 3.5编写的;装载机使用.NET 2.0

回答

0

问题解决了,但静态引用都消失了。我做了一些事情:

首先,我将目标.NET版本更改为4.0。显然,使用4.0编写的BHO效果更好 - 我无法找到证实此声明的链接,但我已在某处阅读它。

更重要的是,我完全不用静态引用。我摆脱了单身人士,而是在我的工具栏类中为每个以前的单身人员类创建了一个属性,该属性将始终是唯一的。然后,每当需要引用前一个单例的类时,我都会传递一个对工具栏的引用。

所以...构造看现在这个样子:

internal class RegistryData 
{ 
    public RegistryData(Toolbar toolbar) 
    { 
      ToolbarRef = toolbar; 
    } 

    ... 
} 

而且我们说RegistryData需要调用消息。

private void RegistryUpdated(int keyId) 
{ 
    ToolbarRef.Messaging.SendMessage(keyId); 
} 

巨大的痛苦,对不对?几小时的工作。但问题解决了。如果这个问题仅与Add-In-Express有关,我不会感到震惊。