【t4必须】OutputHelper.ttinclude 【t4生成多个文件】

创建txt然后修改拓展名为  ttinclude

<#@ assembly name="System.Core"
#><#@ assembly name="System.Data.Linq"
#><#@ assembly name="EnvDTE"
#><#@ assembly name="System.Xml"
#><#@ assembly name="System.Xml.Linq"
#><#@ import namespace="System"
#><#@ import namespace="System.CodeDom"
#><#@ import namespace="System.CodeDom.Compiler"
#><#@ import namespace="System.Collections.Generic"
#><#@ import namespace="System.Data.Linq"
#><#@ import namespace="System.Data.Linq.Mapping"
#><#@ import namespace="System.IO"
#><#@ import namespace="System.Linq"
#><#@ import namespace="System.Reflection"
#><#@ import namespace="System.Text"
#><#@ import namespace="System.Xml.Linq"
#><#@ import namespace="Microsoft.VisualStudio.TextTemplating"
#><#+
// https://raw.github.com/damieng/DamienGKit
// http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited

// Manager class records the various blocks so it can split them up
class Manager {
private class Block {
public String Name;
public int Start, Length;
public bool IncludeInDefault;
}

private Block currentBlock;
private List<Block> files = new List<Block>();
private Block footer = new Block();
private Block header = new Block();
private ITextTemplatingEngineHost host;
private StringBuilder template;
protected List<String> generatedFileNames = new List<String>();

public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
}

public void StartNewFile(String name) {
if (name == null)
throw new ArgumentNullException("name");
CurrentBlock = new Block { Name = name };
}

public void StartFooter(bool includeInDefault = true) {
CurrentBlock = footer;
footer.IncludeInDefault = includeInDefault;
}

public void StartHeader(bool includeInDefault = true) {
CurrentBlock = header;
header.IncludeInDefault = includeInDefault;
}

public void EndBlock() {
if (CurrentBlock == null)
return;
CurrentBlock.Length = template.Length - CurrentBlock.Start;
if (CurrentBlock != header && CurrentBlock != footer)
files.Add(CurrentBlock);
currentBlock = null;
}

public virtual void Process(bool split, bool sync = true) {
if (split) {
EndBlock();
String headerText = template.ToString(header.Start, header.Length);
String footerText = template.ToString(footer.Start, footer.Length);
String outputPath = Path.GetDirectoryName(host.TemplateFile);
files.Reverse();
if (!footer.IncludeInDefault)
template.Remove(footer.Start, footer.Length);
foreach(Block block in files) {
String fileName = Path.Combine(outputPath, block.Name);
String content = headerText + template.ToString(block.Start, block.Length) + footerText;
generatedFileNames.Add(fileName);
CreateFile(fileName, content);
template.Remove(block.Start, block.Length);
}
if (!header.IncludeInDefault)
template.Remove(header.Start, header.Length);
}
}

protected virtual void CreateFile(String fileName, String content) {
if (IsFileContentDifferent(fileName, content))
File.WriteAllText(fileName, content);
}

public virtual String GetCustomToolNamespace(String fileName) {
return null;
}

public virtual String DefaultProjectNamespace {
get { return null; }
}

protected bool IsFileContentDifferent(String fileName, String newContent) {
return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
}

private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
this.host = host;
this.template = template;
}

private Block CurrentBlock {
get { return currentBlock; }
set {
if (CurrentBlock != null)
EndBlock();
if (value != null)
value.Start = template.Length;
currentBlock = value;
}
}

private class VSManager: Manager {
private EnvDTE.ProjectItem templateProjectItem;
private EnvDTE.DTE dte;
private Action<String> checkOutAction;
private Action<IEnumerable<String>> projectSyncAction;

public override String DefaultProjectNamespace {
get {
return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
}
}

public override String GetCustomToolNamespace(string fileName) {
return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
}

public override void Process(bool split, bool sync) {
if (templateProjectItem.ProjectItems == null)
return;
base.Process(split, sync);
if (sync)
projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
}

protected override void CreateFile(String fileName, String content) {
if (IsFileContentDifferent(fileName, content)) {
CheckoutFileIfRequired(fileName);
File.WriteAllText(fileName, content);
}
}

internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
: base(host, template) {
var hostServiceProvider = (IServiceProvider) host;
if (hostServiceProvider == null)
throw new ArgumentNullException("Could not obtain IServiceProvider");
dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE));
if (dte == null)
throw new ArgumentNullException("Could not obtain DTE from host");
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
}

private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
var keepFileNameSet = new HashSet<String>(keepFileNames);
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
projectFiles.Add(projectItem.get_FileNames(0), projectItem);

// Remove unused items from the project
foreach(var pair in projectFiles)
if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
pair.Value.Delete();

// Add missing files to the project
foreach(String fileName in keepFileNameSet)
if (!projectFiles.ContainsKey(fileName))
templateProjectItem.ProjectItems.AddFromFile(fileName);
}

private void CheckoutFileIfRequired(String fileName) {
var sc = dte.SourceControl;
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
}
}
} #>

时间: 2024-10-08 01:21:38

【t4必须】OutputHelper.ttinclude 【t4生成多个文件】的相关文章

用T4生成多个文件(转)

初次认识并尝试使用T4生成代码的时候,相关学习资料似乎比较少.不过现在VS2010 的MSDN里已有相关章节,可参看<代码生成和文本模板>章节.可以用C#的语法写模板,实在舒服很多. 很快就发现T4难以生成多个文件的缺陷,微软似乎也不着急改进这一点.通过搜索,从InfoQ找到一篇文章<用T4生成多个文件>,链接到一篇文章,Damien Guard的扩展可以方便的生成多个文件.原文是英文,能看懂,然而如果翻译则斟酌字词太辛苦. 首先,保存以下代码为一个模板文件(例如保存文件名为Man

t4 根据表名数组生成实体

<#@ template debug="false" hostspecific="true" language="C#" #> <#@ assembly name="System.Core.dll" #> <#@ assembly name="System.Data.dll" #> <#@ assembly name="System.Data.DataSe

T4模板_根据DB生成实体类

为了减少重复劳动,可以通过T4读取数据库表结构,生成实体类,用下面的实例测试了一下 1.首先创建一个项目,并添加文本模板: 2.添加 文本模板: 3.向T4文本模板文件添加代码: <#@ template language="C#" debug="True" hostspecific="True" #> <#@ assembly name="System.Data" #> <#@ assembly

基于T4模板的文档生成

看了好几个代码自动生成的工具,用起来很方便,但有些方面还是不够自由:这些日子里忙里偷闲摸索了一番,个人觉的基于T4模板的代码生成方案还是不错的. 下面就看看这个T4到底是什么东东-- T4 = Text Template Transformation Toolkit 不知道电脑前的你是否接触过Asp或jsp之类的动态网页编程语言,个人感觉就和那些动态网页的的编写思路差不多只不过那些编译前是*.asp.*.aspx,或*.jsp,这个T4编译前是的扩展名是tt(*.tt) 先看一个简单的tt文件

t4模板生成 _references.js 文件

t4模板功能: 指定目录,自动生成 _references.js 文件 相关文件说明: _references.js 实现js智能提示. 注意事项: hostspecific="true" <#@ template debug="false" hostspecific="true" language="C#" #> projectDir=Host.ResolveAssemblyReference("$(P

使用T4模板调用Sqlserver链接生成自己的模板

<#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="Microsoft.CSharp" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq"

自动数据库抽取想要的查询结果,自动生成txt(utf-8)文件,然后自动ftp上传到外网服务器

需求:无人值守的把数据库中的数据,生成txt文本,自动上传到ftp服务器,与外部客户进行数据对接: =============================================== 步骤:1  写存储过程     2  数据库中建立计划任务     3  写转换txt编码格式的插件     4  windows任务计划     5  flashfxp定时上传数据到ftp服务器 ============================================== 详细信息:

Android gen根目录下自动生成的R文件指向问题

今天才弄明白,原来在调用vitamio包的时候使用它们的R文件,然后在迁入广告的时候出现了问题,但是瞎胡搞半天后把问题解决了,可没有明白这是什么原因. 今天更新应用又出现了相同的情况,无意中打开了gen的根目录妈蛋!发现里面的报名根本就不是我现在应用的包名.而是调用的那个工程的包名!这下终于找到根本原因了,但是怎么解决呢???----------->修改包名呗~~~~~~~可是你改了它又会自动生成了原来的那个,--------------后来终于发现原来这个R文件的包名适合manifest文件中

文件分割器,一个读取流,相应多个输出流,并且生成的碎片文件都有有序的编号

import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; public class FileSpilte { /** * @param args * @throws IOException */

VHDL生成的ngc文件被verilog的工程调用的问题

1. 问题的提出 工程a是一个soft core,用VHDL写的,综合的时候去掉了"Add I/O buffers" ,并将-iob(Pack I/O Registers into IOBs)置为否.综合最后生成了a.ngc文件供其他工程使用.在生成完ngc后,还可以在 "Design Utilities" -> "View HDL Instantiation Template" 中生成相应的调用文件. 工程b调用的a.ngc,但是工程b使