Why does my T4 template append a number to the file name?

Solution 1:

This happens when Visual Studio gets itself confused and briefly decides that it can't use Foo.cs as the output for some reason (usually hallucinatory), so it will use Foo1.cs instead, and then insists on remembering this setting.

The fix is to open the .csproj file in a text editor and locate the Foo.tt entry. This should have a sub-element called LastGenOutput. Change this back to Foo.cs, save the project file, and reopen it in VS.

And then -- sigh -- wait for it to happen again. You can see http://social.msdn.microsoft.com/Forums/en/linqtosql/thread/0c0f77a6-d712-43d2-a990-555df7960123 for more details, though nobody seems to be able to explain what causes VS to get into this state or how to stop it doing so...

Solution 2:

@itowlson's answer really helped me out, but I discovered a slightly simpler workaround that I thought I'd share.

If you have:

Filename.tt
└── Filename1.cs

Just rename Filename.tt to Filename2.tt:

Filename2.tt
└── Filename2.cs

And back to Filename.tt again:

Filename.tt
└── Filename.cs

Voilà.

Solution 3:

I've discovered something in VS2019 that might explain one potential cause of the issue.

In the CSPROJ file, VS expects a TT file be included using <Content Include="Generator.tt"> tags. When adding a TT file to a project via Cut/Copy/Paste using the contextual menu items in the interface built into VS, VS may sometimes use the wrong XML tag, such as <None Update="Generator.tt">. This will be despite the fact that if you open the Property sheet for the TT file, it will show 'Content' as the build action.

Open the CSPROJ file, and if you change the <None> tag to <Content> and also the Update attribute to Include, then restart VS, the issue appears to go away.