0

我已经能够使用CreateToolWindow2从 F# Interactive 以编程方式创建一个 VS2010 插件工具窗口,它本身就是一个工具窗口。我传递的Assembly和参数对应于构成工具窗口的(WinForms)。通过out ref 参数“返回”对创建面板的引用。ClassCreateToolWindow2PanelControlObject

用属性标记了面板的程序集后,ComVisible(true)我确实得到了返回的实例,除非我尝试访问实例的任何成员(从 F# Interactive 的上下文中),我得到一个RemotingException:“这个远程代理没有通道接收器,这意味着要么服务器没有注册的服务器通道正在侦听,或者此应用程序没有合适的客户端通道与服务器通信。”

任何想法如何绕过这个障碍?

4

2 回答 2

1

这有点原始,我个人认为它很脏,但总是有使用文件系统来管理通信的后备。指定两个插件都可以访问的临时文件并管理它们之间的锁定,突然之间你就有了一个跨插件通信系统。这当然假设您愿意更改两个插件以使用该方法(我不确定您是否会考虑预先打包的插件之一)。

于 2012-01-30T05:06:37.680 回答
1

使用命名管道的WCF 服务。我现在这样做是为了在一些 WF4 活动的设计表面和 Visual Studio 扩展之间进行交流。

做起来很简单。我无法显示所有代码,因为其中一些代码包含在控制打开和关闭通道的助手中,但定义非常简单,并且全部在代码中完成。

你只需要定义一个绑定

var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport);
binding.ReceiveTimeout = TimeSpan.FromMinutes(1);

创建您的频道

var channelFactory = new ChannelFactory<IServiceInterface>(binding, endpointAddress);

并且您必须确保端点地址在客户端和服务器中都保证相同,它们共享相同的进程但存在于不同的 AppDomain 中。一种简单的方法是将地址范围限定为进程 ID...

private const string AddressFormatString =
    "net.pipe://localhost/Company/App/HostType/{0}";
private static string _hostAddress;

public static string HostAddress()
{
    if (_hostAddress == null)
        _hostAddress = string.Format(
                           AddressFormatString, 
                           Process.GetCurrentProcess().Id);
    return _hostAddress;
}

您将有两个实际副本(一个在客户端 appdomain 中,一个在 addin appdomain 中),但由于它们都在同一个进程中,因此主机地址保证在两者中相同,您不会遇到问题您同时加载了多个 VS 实例(没有可怕的运行对象表,谢谢)。

我将此地址代码保存在基本主机类中。打开主机频道也很简单:

Host = new ServiceHost(this, new Uri(HostAddress()));

var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport);    
Host.AddServiceEndpoint(typeof(IServiceInterface), binding, HostAddress());
Host.Open();
于 2012-01-30T15:04:36.603 回答