3
<#@ template debug="true" hostspecific="true" language="C#" #>  
<#@ assembly name="EnvDTE80" #>  
<#@ include file="T4Toolbox.tt" #>  
<#  
IServiceProvider serviceProvider = (IServiceProvider)this.Host;  
EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)serviceProvider.GetService(typeof(EnvDTE.DTE));  
//add a file to a project and add its dependupon build property. 
//I want to refresh teh solution explorer window to show the hierarchy between 2 files
//You will see this kind of relationship between Forms.cs and Form1.Designer.cs files.

EnvDTE.UIHierarchy solExplorer = dte.ToolWindows.SolutionExplorer;  
solExplorer.Parent.Activate();  
dte.ExecuteCommand("View.Refresh", string.Empty); 

新しく作成されたファイルがネストされていることを確認できるように、ソリューション エクスプローラーのツール ウィンドウを更新しようとしています。T4 テンプレートは 1 つのアプリケーション ドメインで実行され、呼び出しはリモート処理を使用して Visual Studio Appdomain に対して行われることを知っています。シリアル化に関するこのエラーが発生しています。ソリューション エクスプローラー ツール ウィンドウ (solExplorer.Parent) を最初にアクティブ化して更新する方法はありますか (私は言われました)。

アセンブリ 'Microsoft.VisualStudio.Platform.WindowManagement, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' の 'Microsoft.VisualStudio.Platform.WindowManagement.DTE.WindowBase' と入力すると、シリアル化可能としてマークされません。

更新:ゲレスのコメントに基づいています。
ありがとう、Gereth 私はこれを試しましたが、COMException を返します
。Microsoft.VisualStudio.Platform.WindowManagement.DTE.WindowBase クラスのシリアル化に関するエラーはなく、Activate メソッドは成功したようです。 エラーは現在 dte.ExecuteCommand メソッドにあります。

//object dteObject = GetCOMService(serviceProvider, typeof(EnvDTE80.DTE2)); 
object dteObject1 = GetCOMService(serviceProvider, typeof(EnvDTE.DTE));
EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)dteObject1;

次の行を実行すると発生する COMException:

dte.ExecuteCommand("View.Refresh", string.Empty);  

メッセージ「COM コンポーネントへの呼び出しからエラー HRESULT E_FAIL が返されました。」
ソース "EnvDTE80"
StackTrace " at EnvDTE80.DTE2.ExecuteCommand(String CommandName, String CommandArgs)
ErrorCode -2147467259

次に何を試しますか?

ありがとうラド

4

3 に答える 3

2

リモート処理パイプの両端がマネージ コードで記述されていることを CLR が認識すると、COM マーシャリングにとどまらない DTE コマンドのセクションがあります。ただし、これらのコンポーネントが実際には .Net リモート可能に設定されていないが、COM リモート可能に設定されている場合、このタイプのエラーが発生します。

一般に、問題の特定の DTE オブジェクトに対する COM マーシャリングが正しく設定されていれば、次のコードを使用して再び動き出すことができるはずです。通常のサービス呼び出しの代わりに呼び出して、DTE を取得します。

public static Object GetCOMService(IServiceProvider provider, Type type)
{
    Object ret;
    ret = provider.GetService(type);
    if (ret == null)
    {
        return ret;
    }

    try
    {
        return Marshal.GetObjectForIUnknown(Marshal.GetIUnknownForObject(ret));
    }
    catch (Exception)
    {
        return ret;
    }
}
于 2011-10-15T02:30:11.137 に答える