EnvDTE not found in VS2012 works in VS2010

2019-02-16 08:28发布

I'm using EnvDTE to do some code generation within my T4 Templates.

I have the code working correctly in Visual Studio 2010, however I've just started using Visual Studio 2012 and now when I try to run my templates I get the following error

Compiling transformation: Metadata file 'EnvDTE.dll' could not be found 

I don't actually have a reference to EnvDTE in my project as its a Silverlight class library and I wasn't able to add the DLL, however it finds the DLL somehow.

I'm not sure what is difference is between 10 and 12 to cause this.

The following are my imports and assembly definitions from the start of my ttinclude file.

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".generated.cs" #>
<#@ Assembly Name="EnvDTE.dll" #>
<#@ Assembly Name="System.Data" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>

Is there anything I have to do differently to get it working for Visual Studio 2012

2条回答
唯我独甜
2楼-- · 2019-02-16 09:17

After stumbling about the same error i searched a little deeper and found this Microsoft Connect entry.

To fix the problem simply remove the .dll from the assembly name and it works as expected:

<#@ Assembly Name="EnvDTE" #>

Also ensure that the EnvDTE assembly is located within the GAC under C:\Windows\assembly. This will normally automaticaly happen when you install Visual Studio on a machine.

Example

Here is an example that should work out of the box:

<#@ template language="C#" debug="true" hostSpecific="true" #>
<#@ output extension=".txt" #>
<#@ Assembly Name="System.Core" #>
<#@ Assembly Name="System.Design" #>
<#@ Assembly Name="System.Drawing" #>
<#@ Assembly Name="System.Windows.Forms" #>
<#@ Assembly Name="EnvDTE" #>
<#@ import namespace="System" #>
<#@ import namespace="System.CodeDom.Compiler" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Drawing" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Resources.Tools" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="Microsoft.CSharp" #>

All projects currently available within this solution:
<#
    //System.Diagnostics.Debugger.Launch();

    EnvDTE.DTE dte = (EnvDTE.DTE)((IServiceProvider)this.Host)
                       .GetService(typeof(EnvDTE.DTE));

    EnvDTE.Projects projects = dte.Solution.Projects;

    foreach (EnvDTE.Project project in projects)
    {
#>
        <#= project.Name #>
<#
    }
#>

This file was generated at: <#= System.DateTime.Now.ToShortDateString() #> <#= DateTime.Now.ToLongTimeString() #>
查看更多
做个烂人
3楼-- · 2019-02-16 09:18

It appears that VS12 can't figure out where EnvDTE is. Its odd that (as you mentioned in a comment) fusion didn't pick that up. Perhaps it did, but you weren't reading it correctly?

As an aside, when the fusion log lets you down, its time to break out Process Monitor when you can't figure out why an application can't find something that should be there.

You can give a full path for assembly references in T4 templates. In your case, it would be

<#@ Assembly Name="C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies\envdte.dll" #>

(assuming you have EnvDTE in the correct spot). I wouldn't consider this a true solution, and would open a Connect issue with MS about this. Seems like a bug.

查看更多
登录 后发表回答