Inter-addin通信

时间:2012-01-30 04:21:15

标签: c# f# remoting envdte f#-interactive

我能够使用CreateToolWindow2以编程方式从F#Interactive创建一个VS2010 AddIn工具窗口,它本身就是一个工具窗口。我传递给Assembly的{​​{1}}和Class参数对应于构成工具窗口的CreateToolWindow2(WinForms)。通过Panel输出ref参数“返回”对创建的面板的引用。

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

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

WCF service使用named pipes。我现在正在这样做,以便在一些WF4活动的设计界面与视觉工作室扩展之间进行交流。

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

您只需要定义绑定

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