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 模板在一个应用程序域中执行,并使用远程处理对 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 的评论。
谢谢,Gereth 我试过了,但它返回 COMException,
我没有关于 Microsoft.VisualStudio.Platform.WindowManagement.DTE.WindowBase 类的序列化的错误,并且激活方法似乎已经成功。 错误现在出现在 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);  

消息“错误 HRESULT E_FAIL 已从对 COM 组件的调用中返回。”
源“EnvDTE80”
StackTrace“在 EnvDTE80.DTE2.ExecuteCommand(String CommandName, String CommandArgs)
ErrorCode -2147467259

接下来要尝试什么?

谢谢拉德

4

3 回答 3

2

一旦 CLR 注意到远程处理管道的两端都是用托管代码编写的,就有一部分 DTE 命令不会与 COM 封送处理保持一致。但是,鉴于这些组件实际上并未设置为 .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 回答
0

我终于通过卸载和重新加载项目来完成这项工作。必须在解决方案资源管理器中选择该项目,否则您将收到 COMException。

IServiceProvider hostServiceProvider = (IServiceProvider)Host;
// see @GarethJ's answer for the following
DTE2 dte2 = GetCOMService(hostServiceProvider, typeof(EnvDTE.DTE)) as DTE2;
object dteObject1 = GetCOMService(hostServiceProvider, typeof(EnvDTE.DTE));
EnvDTE80.DTE2 dte2 = (EnvDTE80.DTE2)dteObject1;

var solExplorer = dte2.ToolWindows.SolutionExplorer;  
solExplorer.Parent.Activate();
ProjectItem containingProjectItem = dte2.Solution.FindProjectItem(templateFile);
Project project = containingProjectItem.ContainingProject;

UIHierarchy solExplorerHierarchy = solExplorer.Parent.Object as UIHierarchy;
string projectSolutionPath = Path.Combine(dte2.Solution.Properties.Item("Name").Value.ToString(), project.Name);
var projectItem = solExplorerHierarchy.GetItem(projectSolutionPath);
projectItem.Select(vsUISelectionType.vsUISelectionTypeSelect);
dte2.ExecuteCommand("Project.UnloadProject", ""); 
dte2.ExecuteCommand("Project.ReloadProject", "");

然后出现任何新创建的嵌套项。我正在使用 VS2012 和 T4Toolbox 11.7。

于 2013-05-21T10:51:17.503 回答
0

谢谢加雷斯。您的解决方案效果很好。我扩展了我的“GetService”方法:

    private T GetService<T>(Type type) where T : class
    {
        IServiceProvider hostServiceProvider = (IServiceProvider)Host;
        if (hostServiceProvider == null)
        {
            throw new Exception("Host property returned unexpected value (null)");
        }
        object serviceObj = hostServiceProvider.GetService(type);
        try
        {
            serviceObj = Marshal.GetObjectForIUnknown(Marshal.GetIUnknownForObject(serviceObj));
        }
        catch (Exception) { }
        T service = serviceObj as T;
        if (service == null)
        {
            throw new Exception("Unable to retrieve service");
        }
        return service;
    }
于 2015-07-04T20:55:17.250 回答