how to disable T4 template auto-run in visual studio (2012)?
Asked Answered
C

3

12

I have some T4 templates in my project. Whenever I make changes and save the tt file, it auto update the generated files. This is a template that loops all tables in a database and generates about 100+ files. So visual studio hangs for a few seconds every time I save my template and this is annoying. Is there a way to disable to "auto-refresh" function and I can manually run the template through the context menu.

Thanks!

Cinchonine answered 27/11, 2012 at 23:7 Comment(1)
Yeah I'm surprised that "feature" is in visual studio. Hell, I'm surprised it's still in visual studio 2013. It makes developing t4 templates inside of visual studio pretty much impossible.Cahoon
H
12

You could delete TextTemplatingFileGenerator under "Custom Tool" in the file's Properties while you are editing it, and then put it back when you are finished.

Hesketh answered 27/11, 2012 at 23:22 Comment(1)
Thanks for sharing. This work around for sure will work. Wondering if there is better option.Cinchonine
A
1

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. Then I simply created a compiler error in the include file. 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.

e.g. 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.

Hopefully future VS versions will allow you to simply disable the auto-transform.

Alverson answered 4/2, 2014 at 19:50 Comment(0)
N
0

Since the TT is always executed (still), I found a different way to control the output when the TT is executed.

/********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. This gives the benefit of skipping all that preparation (and IDE lag) unless you add the REGEN_CODE_FILES conditional compilation symbol. (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...

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");
Nosedive answered 30/12, 2016 at 20:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.