23

We have a database project in Visual Studio 2013. In this project we have a .tt file which generates .sql script. The problem is after generation the build action of the generated file is automatically set to Build. If we change it manually to None, it gets reset to Build after regenerating (running custom tool).

Another strange thing is that it only happens if .tt file is in database project and in some folder of that project (not in root). if .tt file is in another project (anywhere) or in the root of the database project, the build action of the generated file does not change after regeneration.

We don't have any Visual Studio add-ins and I tried to disable all extensions and updates which could be disabled.

I will give you any details if needed.

nightcoder
  • 13,149
  • 16
  • 64
  • 72
  • 1
    Have you added the [Transform on build](https://msdn.microsoft.com/en-us/library/ee847423.aspx) to the project file? Are any of the files read only? – lloyd May 06 '15 at 12:55
  • @lloydm, No there is no transform on build in the project file. Some of the files in the project are read only. – nightcoder May 06 '15 at 13:53
  • Have you had a look at the solutions posted for running [T4 on every build](http://stackoverflow.com/questions/1646580/get-visual-studio-to-run-a-t4-template-on-every-build)? – lloyd May 07 '15 at 04:43
  • @lloydm, Maybe I misunderstand you, but we don't need to run T4 on every build. – nightcoder May 07 '15 at 14:33
  • 1
    Reproduced - I see no good reason for this to be happening, if I change the extension to .txt then the issue is gone as well. So I guess report a new bug to MS. – Michal Hosala May 08 '15 at 21:53
  • I'm encountering the exact same thing. Sql project, No t4 plugins - annoying as hell. – Kelly Robins May 10 '15 at 02:19
  • In the MSBuild declaration for the item, put the sql item in it's own ItemGroup and make it conditional with a condition that can never be met. The condition appears to be left alone: NewFolder1\TextTemplateSql1.tt – James Lucas May 12 '15 at 13:30
  • @JamesLucas, I edited the "Database.sqlproj" project file as you suggested, but the problem still exists. – nightcoder May 13 '15 at 13:57
  • Related to http://stackoverflow.com/questions/36332947/how-to-set-build-action-for-generated-files-from-a-t4 – debater Jul 12 '16 at 12:55

2 Answers2

2

This answer was kind of mentioned in comments, but someone might miss it. Changed output extension to e.g. ".sqlscript" and default Build Action will be None.

<#@ output extension=".sqlscript" #>

You can also change default editor for this extension to

"Microsoft SQL Server Data Tools, T-SQL Editor"

so you can read and edit it as standard T-SQL script. Just go to

Tools -> Options.. -> Text Editor -> File Extensions.

It does not solve the problem with ".sql" files, but it is a good workaround and works fine for me. I tested it in VS2015 but it probably works similar in VS2013.

zx485
  • 28,498
  • 28
  • 50
  • 59
1

How is the build action stored? In the csproj Note: Compile Generated Class file with a build action of Compile

Note: Compile generatedFile.cs with a build action of None

So now to set it to None.

Ok one T4 template that changes the sqlproj. Note : This is saving a new file for sqlproj instead of writing over your existing sqlproj as you will want to at a minimum :

  1. Backup your sqlproj
  2. Test on a new file
  3. Modify this to backup the sqlproj just in case.
  4. Have a extremely unique file name as the target.
  5. Have this as a separate T4 template
  6. Run this after your custom tool

        <#@ template debug="true" hostSpecific="true" #>
        <#@ output extension=".cs" #>
        <#@ Assembly Name="System.Core" #>
    
        <#@ import namespace="System" #>
        <#@ import namespace="System.IO" #>
        <#@ import namespace="System.Collections.Generic" #>
    
        <# 
        string file  = @"C:\...\MyProject.sqlproj";
    
    
    
            string [] lines = System.IO.File.ReadAllLines(file);
    
    
            //relative path of file you want to change build action
            string target = @"Models\GeneratedClass.cs";
            //find the line that has your class 
            for(int i = 0; i < lines.Length ; i++)
            {
    
                if(lines[i].Contains(target))
                {
                    //Replace Compile with None
                    lines[i].Replace("Compile", "None");
    
                }
            }
    
            string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
            string outputFileName = "newCSProj.sqlproj";
            string outputFilePath = Path.Combine(templateDirectory, outputFileName);
    
            File.WriteAllLines(outputFilePath, lines); 
    
      #>
    

Here is the warning Visual Studios shows before running a Text Template

Security Warning: Running this text template can potentially harm your computer. Do not run it if you obtained it from a untrusted source.

lloyd
  • 1,683
  • 2
  • 19
  • 23
  • and there are better ways of modifying the [project file](http://blogs.msdn.com/b/msbuild/archive/2005/11/07/490068.aspx) – lloyd May 28 '15 at 04:31