可以使用 $(variableName) 语法引用 Visual Studio 或 MSBuild 变量(如 $(SolutionDir)),以及使用 %VariableName% 来引用环境变量。
介绍几个常用的$(variableName) 变量:

$(SolutionDir):当前项目所在解决方案目录
$(ProjectDir):当前项目所在目录
$(TargetPath):当前项目编译输出文件绝对路径
$(TargetDir):当前项目编译输出目录,即web项目的Bin目录,控制台、类库项目bin目录下的debug或release目录(取决于当前的编译模式)

举个例子:比如我们在D盘根目录建立了一个控制台项目TestConsole,解决方案目录为D:\LzrabbitRabbit,项目目录为
D:\LzrabbitRabbit\TestConsole,那么此时在Debug编译模式下
$(SolutionDir)的值为D:\LzrabbitRabbit
$(ProjectDir)的值为D:\LzrabbitRabbit\TestConsole
$(TargetPath)值为D:\LzrabbitRabbit\TestConsole\bin\Debug\TestConsole.exe
$(TargetDir)值为D:\LzrabbitRabbit\TestConsole\bin\Debug\

若要创建运行时模板,请向您的项目中添加“已预处理的文本模板”文件。 另外,您还可以添加纯文本文件并将其“自定义工具”属性设置为“TextTemplatingFilePreprocessor”。
若要创建设计时模板,请向您的项目中添加“文本模板”文件。 另外,您还可以添加纯文本文件并将其“自定义工具”属性设置为“TextTemplatingFileGenerator”。

T4基本结构
T4模板可以分为:指令块、文本块、控制块。
    指令块 - 向文本模板化引擎提供关于如何生成转换代码和输出文件的一般指令。
    文本块 - 直接复制到输出的内容。
    控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码,不能在控制块中嵌套控制块。

6个指令<#@
template #>、<#@ parameter#>、<#@ assembly #>、<#@
import #>、<#@ include #>、<#@ output #>、
其中, output 和 assembly 只能用在设计时模板。

控制块
有三种类型的控制块,根据其左括号对它们进行区分:
1.<# 标准控制块 #>  可以包含语句。
2.<#= 表达式控制块 #>  将一个可以计算为字符串的表达式括起来,用于提供要写入“输出”文件的字符串的代码。
3.<#+ 类功能控制块 #>  可以使用类功能控制块向文本模板添加方法、属性、字段甚至是嵌套类。必须作为文件中的最后一个块显示,或者用<#@ include #>引入外部文件。

注意:
1)始终使用 {...}花括号来包含内嵌的嵌套语句,否则会报错。(哪怕花括号中只有一句代码)
2)控制块不能互相嵌套。必须先终止之前的控制块,然后才能打开另一个。

T4文本模板的断点调试
    注册表:设置DbgJITDebugLaunchSetting值为 2。
    (x86系统): HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
    (x64 系统): HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework

为template指令添加debug="true"特性:<#@ template debug="true"#>
   
    命令:
    <# System.Diagnostics.Debugger.Launch();#>在模板执行到特定点启动调试器。如果用Debugger.Break()启动调试器在调试完后会导致 VS 奔溃。
    <#System.Diagnostics.Debugger.Break();#>启动调试器后,使用此命令在后续特定点处再次进入调试模式,相当于断点。(此种方式会让vs崩溃)

使用方法:必须使用“Debugger.Launch()”命令启动调试器(如下图,启动新实例或使用已存在的VS附加。注意,若此处点击取消则将关闭当前IDE),调试完后可以不用中断调试,不影响模板编辑,当再次编译模板时如果存在“Debugger.Break()”命令则自动进入调试模式。

自定义生成的文件存放路径:
String outputPath = Path.Combine(Path.GetDirectoryName(host.TemplateFile),"Model");

调试的时候发现一个问题:在GetCurrentProject()方法里获取当前项目dte.ActiveSolutionProjects,第一次生成正常,但是一编译项目再生成,这里就获取不到项目了,
Array
activeSolutionProjects = (Array)dte.ActiveSolutionProjects
里面是个空数组,导致生成失败,提示“正在运行转换: System.IndexOutOfRangeException: 索引超出了数组界限”错误。

万般无奈,只好采用避开调用这里的措施:
在.tt模板里,把定义connectionString、dbProviderName的地方重新写死。如:
var connectionStringName = "Northwind";
var dbContextName = Host.TemplateFile.Split('\\')[Host.TemplateFile.Split('\\').Length - 1].TrimEnd('.', 't');
//var connectionStringSetting = GetConnectionStringSettings(connectionStringName);
//var connectionString = connectionStringSetting.ConnectionString;
//var dbProviderName = connectionStringSetting.ProviderName;

var
connectionString = "Data Source=ZHAOWEI-PC\\SQLEXPRESS;Initial
Catalog=Northwind;Persist Security Info=True;User
ID=sa;Password=123456";
var dbProviderName = "System.Data.SqlClient";
var dbConfiguration = DbConfiguration.Configure(connectionString, dbProviderName);
var databaseSchema = dbConfiguration.Schema;
var manager = Manager.Create(Host, GenerationEnvironment);
var namespace1 = manager.DefaultProjectNamespace+".Model";
manager.StartHeader();
。。。。
这样问题暂时解决了。

-------------------------------------------------------------------------------------------------------------
T4模板调试需注意的地方:
1、.tt模板的属性 自定义工具=TextTemplatingFileGenerator,生成操作=无;
      生成的附属文件属性 自定义工具=无,生成操作=编译
2、在下列任何一种情况下,将执行模板,同时生成附属文件:
    编辑该模板,然后将焦点更改到其他 Visual Studio 窗口。
    保存模板。
    单击“生成”菜单中的“转换所有模板”。 这将转换 Visual Studio 解决方案中的所有模板。
    在“解决方案资源管理器”中,在任何文件的快捷菜单上,选择“运行自定义工具”。 使用此方法可以转换选定的模板子集。

<#@ import namespace="EnvDTE" #>

EnvDTE路径:
C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies
<#@ Assembly Name="C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies\envdte.dll" #>
<#@ Import namespace="EnvDTE80" #>
<#@ Import namespace="EnvDTE90" #>
<#@ Import namespace="EnvDTE90a" #>
<#@ Import namespace="EnvDTE100" #>

private EnvDTE.Project getActiveProject(EnvDTE.DTE dte)
{
    Array projects = dte.ActiveSolutionProjects as Array;
    if (projects == null || projects.Length == 0)
    {
        projects = dte.Solution.SolutionBuild.StartupProjects as Array;
        if (projects == null || projects.Length == 0)
        {
            EnvDTE.Projects pro = dte.Solution.Projects;
            if (pro == null || pro.Count == 0)
                return null;
            return pro.Item(0);
        }
    }
    return projects.GetValue(0) as EnvDTE.Project;
}
   
public Project getActiveProject()
{
  Array projects = (Array)_applicationObject.ActiveSolutionProjects;
  if(projects != null && projects.Length > 0)
  {
    return projects.GetValue(0) as Project;
  }
  projects = (Array)_applicationObject.Solution.SolutionBuild.StartupProjects;
  if(projects != null && projects.Length >= 1)
  {
    return projects.GetValue(0) as Project;
  }
  projects = (Array)_applicationObject.Solution.Projects;
  if(projects != null && projects.Length > 0)
  {
    return projects.GetValue(0) as Project;
  }
  return null;
}

待解决问题:
 (Array)dte.ActiveSolutionProjects IndexOutOfRangeException
 (Array)dte.ActiveSolutionProjects 索引超出了数组界限

参考:
https://msdn.microsoft.com/zh-cn/library/gg604090
https://msdn.microsoft.com/zh-cn/library/dd820620
http://www.cnblogs.com/guohu/p/4541418.html
http://blog.chenxu.me/post/detail?id=2c393950-acbe-4367-8039-a326449c8d22
https://social.msdn.microsoft.com/Forums/vstudio/en-US/4b746a30-9f6f-446b-9e1e-54b5ba3f29b7/activesolutionprojects-indexoutofrange?forum=vsx

T4模板生成文件要点记录的更多相关文章

  1. EF CodeFirst 使用T4模板 生成文件

    小编是个实用主义者,并没有深入的去理解T4的原理.只是根据自己的需求,在博客园里的前辈哪里找的资料,结合自己的理解,在项目中使用了T4模板. 最近的项目用了他,很方便,节省了不少代码量. 想利用T4做 ...

  2. 真实项目中VS2015中自建T4模板生成文件的使用

    有可能许多小伙伴们发现,vs2015和2012的自带T4模板中的.tt文件改变非常之多,如果仅仅copyEF系统自己生成的模板文件,那可累了.以下是我自己整理的在2012和2015中都可以试用的代码. ...

  3. MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    前言 经过前面EF的<第一篇>与<第二篇>,我们的数据层功能已经较为完善了,但有不少代码相似度较高,比如负责实体映射的 EntityConfiguration,负责仓储操作的I ...

  4. [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:Hello ...

  5. 使用T4模板生成不同部署环境下的配置文件

    在开发企业级应用的时候,通常会有不同的开发环境,比如有开发环境,测试环境,正式环境,生产环境等.在一份代码部署到不同环境的时候,不同环境的配置文件可能需要根据目标环境不同而不同.比如在开发环境中,数据 ...

  6. CSharpGL(12)用T4模板生成CSSL及其renderer代码

    CSharpGL(12)用T4模板生成CSSL及其renderer代码 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立 ...

  7. 利用T4模板生成ASP.NET Core控制器的构造函数和参数

    前言 在ASP.NET Core中引入了DI,并且通过构造函数注入参数,控制器中会大量使用DI注入各种的配置参数,如果配置注入的参数比较多,而且各个控制器需要的配置参数都基本一样的话,那么不断重复的复 ...

  8. Visual Studio 2013 EF5实体数据模型 EDMX 使用 T4模板生成后使用 ObjectContext对象

    Visual Studio 2013 EF5实体数据模型 EDMX 使用 T4模板生成后的继承对象为DbContext,以前的熟悉的ObjectContext对象不见了,当然使用ObjectConte ...

  9. T4模板生成不同部署环境下的配置文件

    使用T4模板生成不同部署环境下的配置文件 在开发企业级应用的时候,通常会有不同的开发环境,比如有开发环境,测试环境,正式环境,生产环境等.在一份代码部署到不同环境的时候,不同环境的配置文件可能需要根据 ...

随机推荐

  1. Flutter移动电商实战 --(16)切换后页面状态的保持AutomaticKeepAliveClientMixin

    底栏切换每次都重新请求是一件非常恶心的事,flutter 中提供了AutomaticKeepAliveClientMixin 帮我们完成页面状态保存效果. 1.AutomaticKeepAliveCl ...

  2. APP_DEBUG改成false上线之后发现:“页面错误!请稍后再试~

      TP框架 页面错误!请稍后再试 把APP_DEBUG改成false上线之后发现:"页面错误!请稍后再试-". 问题一般是出在,display() 指定某个具体的模板文件后win ...

  3. Google Python Style Guide

    https://google.github.io/styleguide/pyguide.html

  4. Qemu搭建ARM vexpress开发环境(一)

    Qemu搭建ARM vexpress开发环境(一) 标签(空格分隔): Qemu ARM Linux 嵌入式开发离不开硬件设备比如:开发板.外设等,但是如果只是想学习研究Linux内核,想学习Linu ...

  5. microsoft 官方学习资源

    https://devblogs.microsoft.com/dotnet/  :_NET Blog https://docs.microsoft.com/zh-cn/learn/ :Microsof ...

  6. 【401】Python 求合数的所有质数因子

    对于这样的一个题目来说,出看来,可能会想到判断是否为质数,但其实并不需要. 只要按照从2开始遍历,只要遇到可以整除的就是想要的质数,理由是,如果遇到合数的话,那么在此之前一定会遇到这个合数的质因子,因 ...

  7. PHP初中高级学习在线文档下载

    收集了一些框架的学习文档与手册,视频教程,给大家带来了更多的方便,只要收藏与保存于百度云盘就好了,省去了网上到处寻找的时间!大家有需要就收藏保存起来吧! 如果不能下载请到群内获取新的下载地址 QQ群 ...

  8. 运行React Native项目出现白屏,无法运行

    运行React Native出现白屏,无法运行,查看终端报错如下: 原因: 代码中有语法错误,导致运行失败. 其实到这里可以去Xcode查看控制台打印,会提示哪个文件出现错误的. 解决办法: 找到报错 ...

  9. 在Windows操作系统中安装MongoDB

    如何在Windows操作系统中安装MongoDB: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/ 启动Mon ...

  10. Linux使用mount挂载Windows共享文件夹

    https://blog.csdn.net/tojohnonly/article/details/71374984 https://github.com/tojohnonly 现实中会有这样的场景 , ...