我能够使用CreateToolWindow2以编程方式从F#Interactive创建一个VS2010 AddIn工具窗口,它本身就是一个工具窗口。我传递给Assembly
的{{1}}和Class
参数对应于构成工具窗口的CreateToolWindow2
(WinForms)。通过Panel
输出ref参数“返回”对创建的面板的引用。
使用ControlObject
属性标记了我的面板程序集后,我确实返回了实例,除非我尝试访问实例的任何成员(来自F#Interactive的上下文),我得到{{1} }:“此远程处理代理没有通道接收器,这意味着服务器没有正在侦听的注册服务器通道,或者此应用程序没有合适的客户端通道与服务器通信。”
任何想法如何绕过这个障碍?
答案 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();