简体   繁体   English

如何禁用Visual Studio中的T4模板自动运行(2012)?

[英]how to disable T4 template auto-run in visual studio (2012)?

I have some T4 templates in my project. 我的项目中有一些T4模板。 Whenever I make changes and save the tt file, it auto update the generated files. 每当我进行更改并保存tt文件时,它都会自动更新生成的文件。 This is a template that loops all tables in a database and generates about 100+ files. 这是一个循环数据库中所有表并生成大约100多个文件的模板。 So visual studio hangs for a few seconds every time I save my template and this is annoying. 因此,每当我保存模板时,visual studio会挂起几秒钟,这很烦人。 Is there a way to disable to "auto-refresh" function and I can manually run the template through the context menu. 有没有办法禁用“自动刷新”功能,我可以通过上下文菜单手动运行模板。

Thanks! 谢谢!

您可以在编辑时删除文件属性中“自定义工具”下的TextTemplatingFileGenerator,然后在完成后将其放回。

I had a similiar issue. 我有一个类似的问题。 I found a quick work around by creating a ttinclude file (actually this was already a standard include file containing utility functions for my templates) and including it in all of my T4 templates. 我通过创建一个ttinclude文件找到了一个快速的解决方法(实际上这已经是包含我的模板的实用程序函数的标准包含文件)并将其包含在我的所有T4模板中。 Then I simply created a compiler error in the include file. 然后我只是在include文件中创建了一个编译器错误。 Thus when the generator attempted to run it would simply fail on the compile. 因此,当生成器试图运行时,它将在编译时失败。 Then when I'm ready to actually generate, I get rid of the offending code and then generate. 然后,当我准备好实际生成时,我摆脱了有问题的代码,然后生成。

eg To cause a failure: 例如导致失败:

<#+

#

#>

To disable the failure: 要禁用失败:

<#+

//#

#>

You can also use this trick in the T4 template itself if you just want to disable the one you're working on. 如果你只想禁用你正在使用的那个,你也可以在T4模板中使用这个技巧。

Hopefully future VS versions will allow you to simply disable the auto-transform. 希望未来的VS版本允许您简单地禁用自动转换。

Since the TT is always executed (still), I found a different way to control the output when the TT is executed. 由于TT始终执行(静止),我发现在执行TT时控制输出的方法不同。

/********SET THIS TO REGENERATE THE FILE (OR NOT) ********/

var _RegenerateFile = true;

/********COS VS ALWAYS REGENERATES ON SAVE ***************/

// Also, T4VSHostProcess.exe may lock files. 
// Kill it from task manager if you get "cannot copy file in use by another process"

var _CurrentFolder = new FileInfo(Host.ResolvePath(Host.TemplateFile)).DirectoryName;
var _AssemblyLoadFolder = Path.Combine(_CurrentFolder, "bin\\Debug");

Directory.SetCurrentDirectory(_CurrentFolder);
Debug.WriteLine($"Using working folder {_CurrentFolder}");

if (_RegenerateFile == false)
{
    Debug.WriteLine($"Not Regenerating File");
    var existingFileName = Path.ChangeExtension(Host.TemplateFile, "cs"); 
    var fileContent = File.ReadAllText(existingFileName);
    return fileContent;
}

Debug.WriteLine($"Regenerating File"); //put the rest of your usual template

Another way (what I eventually settled on) is based on reading a conditional compilation symbol that sets a property on one of the the classes that is providing the data for the T4. 另一种方式(我最终确定的)基于读取条件编译符号,该符号在为T4提供数据的类之一上设置属性。 This gives the benefit of skipping all that preparation (and IDE lag) unless you add the REGEN_CODE_FILES conditional compilation symbol. 除非添加REGEN_CODE_FILES条件编译符号,否则这将有利于跳过所有准备(和IDE滞后)。 (I guess this could also be made into a new solution configuration too. yes, this does work and removes the need for the class change below ) (我想这也可以成为一个新的解决方案配置。 是的,这确实有效,并且无需在下面进行类更改

An example of the class i am calling in the same assembly.. 我在同一个程序集中调用的类的示例..

public class MetadataProvider
{
    public bool RegenCodeFile { get; set; }

    public MetadataProvider() 
    {

#if REGEN_CODE_FILES
        RegenCodeFile = true; //try to get this to set the property
#endif
        if (RegenCodeFile == false)
        {
            return;
        }
        //code that does some degree of preparation and c...
    }
}

In the TT file... 在TT文件中......

var _MetaProvider = new MetadataProvider();
var _RegenerateFile = _MetaProvider.RegenCodeFile;

// T4VSHostProcess.exe may lock files. 
// Kill it from task manager if you get "cannot copy file in use by another process"

var _CurrentFolder = new FileInfo(Host.ResolvePath(Host.TemplateFile)).DirectoryName;
var _AssemblyLoadFolder = Path.Combine(_CurrentFolder, "bin\\Debug");

Directory.SetCurrentDirectory(_CurrentFolder);
Debug.WriteLine($"Using working folder {_CurrentFolder}");

if (_RegenerateFile == false)
{
    Debug.WriteLine($"Not Regenerating File");
    var existingFileName = Path.ChangeExtension(Host.TemplateFile, "cs"); 
    var fileContent = File.ReadAllText(existingFileName);
    return fileContent;
}

Debug.WriteLine($"Regenerating File");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM