I was trying to follow Oleg Sych's tutorials on T4 http://www.olegsych.com/2008/09/t4-tutorial-creatating-your-first-code-generator/, kinduva "Hello, Northwind!" but right away in the second step (at bottom) I got ten "missing assembly" errors like this
Error 1 Compiling transformation: The type >'Microsoft.SqlServer.Management.Sdk.Sfc.ISfcValidate' is defined in an assembly that is >not referenced. You must add a reference to assembly >'Microsoft.SqlServer.Management.Sdk.Sfc, Version=10.0.0.0, Culture=neutral, >PublicKeyToken=89845dcd8080cc91'.
I made sure all the sql server assemblies from (list below) are in %windir%\assembly (I think that’s the GAC), but no good. I added the assemblies to the visual-studio project; no good. I guess the only thing I can do is add absolute paths to the assemblies, but that is a HORRIBLE solution since I can’t share the solution with programmers who don’t have exactly the same absolute paths. Any ideas how to fix this, please & thanks?
<## template language="C#" #>
<## output extension="SQL" #>
<## assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<## assembly name="Microsoft.SqlServer.Smo" #>
<## import namespace="Microsoft.SqlServer.Management.Smo" #>
<#
Server server = new Server();
Database database = new Database(server, "Northwind");
Table table = new Table(database, "Products");
table.Refresh();
#>
create procedure Products_Delete
#ProductID int
as
delete from Products
where ProductID = #ProductID
Here's stuff I put in the GAC
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.WmiEnum.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.ReportingServices.Interfaces.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.ConnectionInfo.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.ConnectionInfoExtended.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Dmf.Adapters.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Dmf.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.DmfSqlClrWrapper.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Management.Collector.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Management.CollectorEnum.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Management.Sdk.Sfc.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Management.Utility.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Management.UtilityEnum.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.PolicyEnum.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.RegSvrEnum.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.ServiceBrokerEnum.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Smo.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.SmoExtended.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.SqlEnum.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.SqlWmiManagement.dll"
"C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.SString.dll"
You can reference GACd assemblies by using the partial strongname (i.e. omitting the ".dll")
for example, use
<# assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
I was recieving the same problem, my fix was adding
<## assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
That seemed to work for me
Mine looks like this now
<## template language="C#v3.5" hostspecific="True" debug="True" #>
<## output extension="SQL" #>
<## include file="T4Toolbox.tt" #>
<## assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<## assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
<## assembly name="Microsoft.SqlServer.Smo" #>
<## import namespace="Microsoft.SqlServer.Management.Smo" #>
<#
Server server = new Server(#"localhost\mssql2008");
Database database = new Database(server, "BreakAway");
Table table = new Table(database, "Contact");
table.Refresh();
#>
I had the same issue. I could resolve it adding some assemblies ...
<## template language="C#" Debug="true"#>
<## output extension="SQL" #>
<## assembly name="System.Xml" #>
<## assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<## assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
<## assembly name="Microsoft.SqlServer.Smo" #>
<## import namespace="Microsoft.SqlServer.Management.Smo" #>
<#
Server server = new Server(#"SQLInstanceName");
Database database = new Database(server, "DBName");
Table table = new Table(database, "Countries");
table.Refresh();
#>
I ran into a similar problem, while trying to get started working with T4. Adding a reference to the Microsoft.SqlServer.Scripting NuGet package fixed the assembly-related issues I was running into.
Related
Using VS2022 17.2.0 Preview 2.0 to generate data layer using T4 templates.
Part of the T4 uses VS interop / DTE to access projects in solution.
The following T4 is a test:
<## template debug="false" hostspecific="true" language="C#" #>
<## assembly name="Microsoft.VisualStudio.Shell.Interop"#>
<## import namespace="Microsoft.VisualStudio.Shell"#>
<## import namespace="Microsoft.VisualStudio.Shell.Interop"#>
<## import namespace="EnvDTE" #>
<## import namespace="EnvDTE80" #>
<## output extension=".txt" #>
<#
var hostServiceProvider = Host as IServiceProvider;
var dte = hostServiceProvider.GetService(typeof(DTE)) as DTE2;
foreach (Project project in dte.Solution)
{
#><#= project.Name #>
<#
}
#>
This produces following exception:
Error Running transformation: System.Runtime.Serialization.SerializationException: Type 'Microsoft.VisualStudio.CommonIDE.Solutions.CMiscProject' in Assembly 'Microsoft.VisualStudio.CommonIDE, Version=17.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable.
Issue did not exist in Preview 1.0 or in VS2019.
I have had a look around and pulled in nuget package for Microsoft.VisualStudio.Interop, version 17.1.32210.191, but problem persists when accessing anything through the EnvDTE.DTE(2).
I know I'm jumping the gun on this as it is a preview version, but has anyone had this issue and solved it? Is there a different approach needed to access projects in the solution from the T4 template?
The error does not occur when debugging the T4 template.
I had a bit of a play (and a lot of a Google) and found the following solved it for me under VS 2022:
Ensure you have the following assemblies and namespaces
<## assembly name="Microsoft.VisualStudio.Interop" #>
<## import namespace="EnvDTE" #>
<## import namespace="EnvDTE80" #>
<## import namespace="Microsoft.VisualStudio.TextTemplating" #>
and then swap out the IServiceProvider's GetService for GetCOMService
//var dte = hostServiceProvider.GetService(typeof(DTE)) as DTE2;
var dte = hostServiceProvider.GetCOMService(typeof(DTE)) as DTE2;
Mostly from answer here: https://stackoverflow.com/a/53346767/2797450
In VS2017 Community, I cannot debug T4 Templates, which works in 2015.
I have a very basic template, such as this...
<## template debug="true" hostspecific="false" language="C#" #>
<## output extension=".txt" #>
<#
var a = "Hello";
var b = "World";
#>
<#=($"{a} {b}!")#>
Run Custom Tool and Transform All T4 Templates both options work, and text file contains expected output
Hello World!
If I put breakpoint somewhere and use Debug T4 Template from the context menu of .tt, it throws this error
Unable to start transformation run creation process.
However it works fine in VS 2015, and I'm able to debug there.
What I could be missing? how to debug T4 Templates in VS 2017? Note that I don't have any Tool/ Extension installed in VS2015 to debug T4
I have had the same issue, I don't know why it doesn't work this way but I have a work around.
Set debug to true, and add the diagnostic namespace
<## template language="C#" debug="true" #>
<## import namespace="System.Diagnostics" #>
In your T4 template write
Debugger.Launch();
Then run your template (easiest way it just to save it) and it will ask if you would like to debug in a new instance of visual studio.
The easiest solution is to just add these two lines to the top of your T4 template.
<## template debug="true" hostspecific="false" language="C#" #>
<# System.Diagnostics.Debugger.Launch(); #>
Then just run the template by saving the file and visual studio will prompt you to debug in a new instance.
If you use Host in your template and you get the error The name 'Host' does not exist in the current context then set `hostspecific="true"'.
I'm using EnvDTE to do some code generation within my T4 Templates.
I have the code working correctly in Visual Studio 2010, however I've just started using Visual Studio 2012 and now when I try to run my templates I get the following error
Compiling transformation: Metadata file 'EnvDTE.dll' could not be found
I don't actually have a reference to EnvDTE in my project as its a Silverlight class library and I wasn't able to add the DLL, however it finds the DLL somehow.
I'm not sure what is difference is between 10 and 12 to cause this.
The following are my imports and assembly definitions from the start of my ttinclude file.
<## template debug="true" hostSpecific="true" #>
<## output extension=".generated.cs" #>
<## Assembly Name="EnvDTE.dll" #>
<## Assembly Name="System.Data" #>
<## import namespace="EnvDTE" #>
<## import namespace="System.Data" #>
<## import namespace="System.Data.SqlClient" #>
<## import namespace="System.IO" #>
<## import namespace="System.Text.RegularExpressions" #>
Is there anything I have to do differently to get it working for Visual Studio 2012
It appears that VS12 can't figure out where EnvDTE is. Its odd that (as you mentioned in a comment) fusion didn't pick that up. Perhaps it did, but you weren't reading it correctly?
As an aside, when the fusion log lets you down, its time to break out Process Monitor when you can't figure out why an application can't find something that should be there.
You can give a full path for assembly references in T4 templates. In your case, it would be
<## Assembly Name="C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies\envdte.dll" #>
(assuming you have EnvDTE in the correct spot). I wouldn't consider this a true solution, and would open a Connect issue with MS about this. Seems like a bug.
After stumbling about the same error i searched a little deeper and found this Microsoft Connect entry.
To fix the problem simply remove the .dll from the assembly name and it works as expected:
<## Assembly Name="EnvDTE" #>
Also ensure that the EnvDTE assembly is located within the GAC under C:\Windows\assembly. This will normally automaticaly happen when you install Visual Studio on a machine.
Example
Here is an example that should work out of the box:
<## template language="C#" debug="true" hostSpecific="true" #>
<## output extension=".txt" #>
<## Assembly Name="System.Core" #>
<## Assembly Name="System.Design" #>
<## Assembly Name="System.Drawing" #>
<## Assembly Name="System.Windows.Forms" #>
<## Assembly Name="EnvDTE" #>
<## import namespace="System" #>
<## import namespace="System.CodeDom.Compiler" #>
<## import namespace="System.Collections.Generic" #>
<## import namespace="System.Drawing" #>
<## import namespace="System.IO" #>
<## import namespace="System.Linq" #>
<## import namespace="System.Resources" #>
<## import namespace="System.Resources.Tools" #>
<## import namespace="EnvDTE" #>
<## import namespace="Microsoft.CSharp" #>
All projects currently available within this solution:
<#
//System.Diagnostics.Debugger.Launch();
EnvDTE.DTE dte = (EnvDTE.DTE)((IServiceProvider)this.Host)
.GetService(typeof(EnvDTE.DTE));
EnvDTE.Projects projects = dte.Solution.Projects;
foreach (EnvDTE.Project project in projects)
{
#>
<#= project.Name #>
<#
}
#>
This file was generated at: <#= System.DateTime.Now.ToShortDateString() #> <#= DateTime.Now.ToLongTimeString() #>
I was facing the issue related to EnvDTE80 on my visual studio 2019 while loading an application.
Error displayed the following message:
"Reference.svcmap: Could not load file or assembly "'EnvDTE," Version=8.0.0.0, Culture=neutral..."
I cleaned the solution and installed the nuget package for version 8.0.0.0. Then rebuilt the solution. In that way my visual studio was able to load the application.
How can I use Linq in a T4 template
This is my software environment information
vs2012
.net version 4.0
This is t4 template:
<## templatedebug="true" hostSpecific="true" #>
<## output extension=".cs" #>
<## Assembly Name="System.Core.dll" #>
<## import namespace="System" #>
<## import namespace="System.Linq" #>
When I call engine.ProcessTemplate(inputTemplate, host), it returns the contents of
ErrorGeneratingOutput. Why is that?
Old question I know, but I've just found the same thing.
When you reference System.Core, don't include .dll:
<## assembly name="System.Core" #>
You need to look at the error in the errors window of visual studio to see more information.
Also you can right click the .tt file and say debug template.
I'm trying to run a T4 template that opens a XML file and uses it contents to generate a code artifact. However, I'm getting the an error message when I try to run a T4 template similar to the one below
<## template debug="false" hostspecific="false" language="C#" #>
<## assembly name="System.Xml.dll" #>
<## assembly name="System.Xml.Linq.dll" #>
<## import namespace="System.IO" #>
<## import namespace="System.Xml" #>
<## import namespace="System.Xml.Linq" #>
<## output extension=".cs" #>
namespace ConsoleApplication1
{
<# XElement fragment = XElement.Load("data.xml"); #>
...
Visual Studio 2010 error list is showing the following message
Running transformation: System.IO.FileNotFoundException: Could not find file 'C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\data.xml'.
It is trying to open the file on the path where the TextTemplateFileGenerator custom tool runs. I'd like it to open the file relative to my project path, because other developers on my team use different folder structures. Does anyone know if it is something possible to accomplish?
Change hostspecific option in template directive to "true" and call Host.ResolvePath("data.xml").
I had a similar problem but Host.ResolvePath didn't work for me because my relative path contained "..\.." in it. I worked around it by doing this:
string ttpath = this.Host.TemplateFile;
string resolvedPath = Path.GetFullPath(Path.GetDirectoryName(ttpath) + #"..\..\<Path To File>");