Add template file without custom tool to project programmatically - visual-studio

We add a structure of T4 template files (tt and ttinclude ones) in a project in Visual Studio.
For these templates we are using our custom transformation and processing and we do NOT want the Custom Tool setting of the tt files which by default is set to TextTemplatingFileGenerator.
In order to achieve that we are using the following code:
... // logic for the files creation
ProjectItem addedItem = this.project.ProjectItems.AddFromFile(fileFullPath);
addedItem.Properties.Item("CustomTool").Value = string.Empty;
The problem is that when the files are added to the project a code generation is caused by the default custom tool and even after we remove it from the properties of the tt files the errors caused by the transformation are still in the Errors List (its something like visual glitch).
They disappear as soon as you save a file, navigate to other file or build the project but we do not want our users to see these errors and make any additional actions to get rid of them.
We tried to access the errors collection using the DTE and DTE2 classes like
DTE2 dte2 = (DTE2)this.project.DTE;
dte2.ToolWindows.TaskList;
or getting them from the ErrorListProvider provider as
var provider = new ErrorListProvider(this.ServiceProvider);
var tasks = provider.Tasks;
but the TaskList is not containing these errors - may be the reason is that they are transformation errors not a compile ones.
Even more strange is that the DTE.Events.TaskListEvents.TaskAdded event is firing for each of the transformation errors but they cannot be found in the TaskList. Also calling the Delete() method of the errors got from the TaskAdded event is not removing them from the errors list.
We also tried to programmatically navigate through the files or save the tamplates but it is not refreshing the errors list like when doing it manually.
How can we refresh the ErrorList or tell Visual Studio not to add a Custom Tool setting when we add the templates to the Project?
P.S. We do not want to force a build of the project of the clients (it is removing the errors but it is not applicable for us).

We found a dirty workaround to get rid of the errors.
We generate the template files with their basic template content (the one below) which is valid for the default TextTemplatingFileGenerator and the initial code generation is not causing any errors.
<## template debug="true" hostSpecific="true" #>
<## output extension=".cs" #>
<## Assembly Name="System.Core" #>
<## Assembly Name="System.Windows.Forms" #>
<## import namespace="System" #>
<#
// This is a temporary content valid for the TextTemplatingFileGenerator.
#>
Then after removing the custom tool setting we replace the content with the real one and everything is working as expected because the files are already in the Project and there are not any other transformations without a custom tool.
Not the best solution but we were not able to find better. I hope this helps.

Related

visual studio 2010 inserts using directives inside namespace

I have exactly opposite problem to one described here. In my case Visual Studio inserts using directives inside namespace and I want to prevent this. I did try to uncheck Resharper option:
Languages -> C# -> Formatting Style -> Namespace Imports -> Add using directive to the deepest scope
And it didn't help. Also I tried to temporary disable the Resharper. Still same issue.
Btw, I have StyleCop and StyleCop+ installed as well. Maybe it is causing the issue.
So right now when I go and Add New Item -> Class - it will create new code file with using directives inside namespace. How to change this?
Have you replace your class template file with one that has one or more using directives inside the namespace declaration? If so, you're probably seeing the result of an interesting bit of C# plugin behavior: a newly added using directive is placed after the last recognized using directly already in the file, regardless of where that is.

Finding T4 text template class code

T4 text templates can be used to generate not only code but also any kind of text with visual studio.
I've read blogs and tutorials about T4 and as far as I can understand, visual studio dynamically builds a class in the background, compiles and runs the code in that class to build the text output.
Is it possible to see the source code of that class?
Yes, the easiest way is to change the Custom Tool in the properties window when the template file is selected in Solution Explorer.
By default, it will be 'TextTemplatingFileGenerator'.
If you change the custom tool to 'TextTemplatingFilePreprocessor' you'll get the underlying template class instead of the template output generated into your project.
To be precise, this code won't be exactly the same as that which is run under the covers, but it will be very close.
If you need the absolute exact code, you should leave the custom tool alone, but set the debug="true" flag on your <## template #> directive. This will then leave the generated code sitting around in a random named '.cs' or 'vb' file in your %TEMP% directory. Just sort the directory by time and it should be up at the top.

T4 Template Get Attributes

I am trying to customise the T4 templates used in MVCScaffolding.
I would like to filter out properties which are have the NotMapped attribute.
My problem is that the attribute collection seems to be empty. I have tried printing out the attributes like below:
List<ModelProperty> properties = GetModelProperties(Model.ViewDataType, true);
foreach (ModelProperty property in properties) {
if (!property.IsPrimaryKey && !property.IsForeignKey) {
#>
<th>
#Html.LabelFor(x => x.First().<#= property.Name #>)
<!--
<#foreach(var attribute in property.Type.CodeType.Attributes)
{#>
Attribute: <#=attribute.GetType().Name#>
<#}#>
-->
</th>
<#
}
}
#>
I cannot find any information about this which actually works and so far it is a very slow case of trial and error. What is the correct way to get the attributes or to get the template to ignore unmapped attributes?
It's not an exact answer to your question but it will provide more information about the problem. I have experienced exactly the same. There are some strange things about this issue:
It worked before. I run the same code (it’s from source control so I’m sure) as 2 months ago and today it’s failing.
The same code when run from outside of T4 engine (e.g. MVC application) works perfectly fine.
I have altered my code so it can be run from outside of Visual Studio:
string assemblyPath = Host.ResolveAssemblyReference("$(ProjectDir)$(OutDir)T4Mvc.dll");
was changed to:
string assemblyPath = #"D:\AbsolutePath\bin\T4Mvc.dll";
Then I used TextTransform.exe instead of RMB > Run Custom Tool
use
TextTransform.exe AjaxServices.tt -out AjaxServices.js
(You can find TextTransform.exe in: "C:\Program Files (x86)\Common Files\microsoft shared\TextTemplating\10.0" ).
Also I have disabled hostspecific flag.
The same template when executed from TextTransform.exe instead of VS worked perfectly. It seems that it’s some kind of problem with VS.
Please try using TextTransform. exe and tell if it works.

Custom Visual Studio Context Menus

I want to use T4 templates to automatically create some code but I want to add a user input box (to ask for a name, for example) similar to the MVC3 "Add View" / "Add Controller" dialog when you right click on a specific folder. Is this possible with pure T4 templates or is it going to result in a writing a VS plugin DLL? If it involves writing a DLL can I just plop that into the projects reference and use it per-project or does it have to be registered individually on each machine?
Managed to figure it out. I probably should of tried this first. Just add the required imports to your T4 template:
<## assembly name="System.Windows.Forms.dll" #>
<## assembly name="System.Drawing.dll" #>
<## import namespace="System.Windows.Forms" #>
<## import namespace="System.Drawing" #>
and then create a form programmatically with a label, input box and button. On DialogResult.OK (for example) just read the input value and do what you need with it. Works perfectly :-)

what is and where can I find MvcTextTemplateHost

I would like to know what this is MvcTextTemplateHost. I have this in my create.tt but I cant find it in my bin folder (searching with object viewer). I read up and found out it's in my
VisualStudio.Extensions.web.dll but I cant find this dll
I've read this
T4 References for 'MvcTextTemplateHost' and 'VisualStudio'.
I would just like to know what properties and methods this class has. I would love a t4 text editor. I installed a few but nothing gives me intellisense for this class thank you.
MvcTextTemplateHost is "Host" of MVC 3.0 (Add>View and Add>Controller) Dialog and maintain user interactions:
so it is not available outside of the tool. When you provide "Scaffolding" template (a .tt file) a manager passes these user inputs to host so host will have those properties.
The class is packaged in:
($VSDIR)\Common7\IDE\Microsoft.VisualStudio.Web.Mvc.3.01.dll
Hope it helps.
In my case the solution was. add these line en controllerWithContext.tt
<## assembly name="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Microsoft.VisualStudio.Web.Mvc.3.01.dll" #>
next to:
<## import namespace="System.Reflection" #>
before:
<## import namespace="Microsoft.VisualStudio.Web.Mvc.Scaffolding.BuiltIn" #>
good luck
You can find all .tt files in VS installation direction, for example to get MVC4 .tt files, go to: ($VSDir)\Common7\IDE\ItemTemplates\CSharp\Web\MVC 4\CodeTemplates
To get the list of the properties of MvcTextTemplateHost, as they are dynamic, you can add the following code to your .tt file:
<#
Type myType = mvcHost.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
foreach (PropertyInfo prop in props)
{
#>
<#= prop.Name #>
<#
}
#>
I ran it as I create a List View in MVC4, and some of the properties that came up are:
ViewName
IsPartialView
IsContentPage
ReferenceScriptLibraries
AutoEventWireup
MasterPageFile
...
I had the same problem after installing the T4 templates for modifying Visual Studio's auto generated CRUD pages described in this question: How do I create my own Scaffold Template in ASP.NET MVC 3?
The solution for me was just to just close Visual Studio 2012 and say Yes to saving the solution. When I reopened it everything compiled fine again, magically. The comments on this answer suggest this has worked for similar situations: https://stackoverflow.com/a/13816299/176877

Resources