0

CreateToolWindow2を使用して、それ自体がツール ウィンドウである F# Interactive から VS2010 アドイン ツール ウィンドウをプログラムで作成することができました。ツール ウィンドウを構成する (WinForms)に対応する引数AssemblyClass引数を渡します。作成されたパネルへの参照は、 out ref 引数を介して「返されます」。CreateToolWindow2PanelControlObject

ComVisible(true)(F# Interactive のコンテキストから) インスタンスのメンバーにアクセスしようとした場合を除いて、返されるインスタンスを取得する属性でパネルのアセンブリをマークすると、RemotingException「このリモート プロキシにはチャネル シンクがありません。つまり、次のいずれかを意味します。サーバーにはリッスンしている登録済みのサーバー チャネルがないか、このアプリケーションにはサーバーと通信するための適切なクライアント チャネルがありません。」

このハードルを回避する方法はありますか?

4

2 に答える 2

1

少し原始的で、個人的には汚いと思いますが、ファイルシステムを使用して通信を管理するというフォールバックが常にあります。両方のアドインからアクセスできる一時ファイルを指定し、アドイン間のロックを管理すると、突然アドイン間の通信システムができあがります。もちろん、これは、両方のアドインを変更してこのアプローチを使用することに慣れていることを前提としています (問題のアドインの 1 つがパッケージ化されていると考えるかどうかはわかりません)。

于 2012-01-30T05:06:37.680 に答える
1

名前付きパイプを使用するWCF サービス。いくつかの WF4 アクティビティのデザイン サーフェイスとビジュアル スタジオ拡張機能の間で通信するために、現在これを行っています。

やり方はとても簡単です。一部のコードはチャネルの開閉を制御するヘルパーにラップされているため、すべてのコードを表示することはできませんが、定義は非常に単純で、すべてコードで行われます。

バインディングを定義するだけです

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

あなたのチャンネルを作成する

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

また、エンドポイント アドレスがクライアントとサーバーの両方で同じであることが保証されていることを確認する必要があります。どちらも同じプロセスを共有しますが、異なる AppDomains に存在します。これを行う簡単な方法は、アドレスをプロセス 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;
}

これの 2 つの実際のコピー (クライアント appdomain に 1 つ、アドイン appdomain に 1 つ) がありますが、両方とも同じプロセスにあるため、ホスト アドレスは両方で同じであることが保証され、問題は発生しません。 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 に答える