5

I am trying to get up to speed with T4 templates. I found the following example (here):

<#@ template hostspecific="True" #>
<#@ output extension="txt" #>
<#@ include file="T4Toolbox.tt" #>
<#@ import namespace="EnvDTE" #>
<#
  CodeEnum enumeration = GetEnum("ContactType.cs");
  WriteLine("Found enumeration " + enumeration.Name);
  foreach (CodeElement element in enumeration.Children)
  {
    CodeVariable value = element as CodeVariable;
    if (value != null)
      WriteLine("… found value " + value.Name);
  }
#>
<#+
  private CodeEnum GetEnum(string enumFile)
  {
    ProjectItem projectItem = TransformationContext.FindProjectItem(enumFile);
    FileCodeModel codeModel = projectItem.FileCodeModel;
    return FindEnum(codeModel.CodeElements);
  }

  private CodeEnum FindEnum(CodeElements elements)
  {
    foreach (CodeElement element in elements)
    {
      CodeEnum enumeration = element as CodeEnum;
      if (enumeration != null)
        return enumeration;
      enumeration = FindEnum(element.Children);
      if (enumeration != null)
        return enumeration;
    }
    return null;
  }
#>

Somehow none of the types that are in the EnvDTE namespace are recognized. I am using the Visual T4 extension. All EnvDTE types are underlined in red. The template doesn't run, and I'm getting a list of errors like:

The type or namespace ... could not be found (are you missing a using directive or assembly reference?)

Does anyone know how to solve this?

jkokorian
  • 2,905
  • 7
  • 32
  • 47

4 Answers4

2

try to use like this

 DTE env = GetVSEnvironment();    

....

private DTE GetVSEnvironment() {
            DTE env = null;
            var provider = Host as IServiceProvider;
            if (provider != null) {
                env = provider.GetService(typeof(DTE)) as DTE;
            }

            if (env == null) {
                throw new InvalidOperationException("Template must be executed from Visual Studio");
            }

            return env;
        }

now you do env.blablabla eg: env.Solution.FindProjectItem(Host.TemplateFile).ContainingProject;

Vibeeshan Mahadeva
  • 7,147
  • 8
  • 52
  • 102
2

Hmm, I'd think that the following include

<#@ template hostspecific="True" #>

would pull in the assembly, but maybe not. First, try adding the following to the top of your template.

<#@ Assembly Name="EnvDTE" #>

If that doesn't work, try adding the full path. For me, its

<#@ Assembly Name="C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies\envdte.dll" #>
GarethJ
  • 6,496
  • 32
  • 42
  • I tried both, the first one didn't do anything. The second one produces the following error: `Error 1 Compiling transformation: An assembly with the same identity 'EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' has already been imported. Try removing one of the duplicate references. D:\jkokorian\My Documents\Visual Studio 2010\Projects\T4TemplatesTestMVC4\T4TemplatesTestMVC4\Models\MyFirstTemplate.tt ` – jkokorian Sep 18 '12 at 14:11
  • @jkokorian: Well, at least you know the assembly is loaded. Uninstall/reinstall the T4 editor? Perhaps switch to another one? –  Sep 18 '12 at 16:56
  • Also try setting your CustomTool property to "TextTemplatingFileGenerator" instead of the default "TextTemplatingFillePreProcessor". Select your .tt file in solution explorer, right click and view properties :) – Chris Schaller Jan 12 '18 at 01:56
2

Have you added a reference to ENVDTE and ENVDTE80 (90, etc) to your project?

podiluska
  • 50,950
  • 7
  • 98
  • 104
0

Adding this line this worked for me:

<#@ Assembly Name="EnvDTE" #>
MIWMIB
  • 1,407
  • 1
  • 14
  • 24