locked
[VS2010 T4] Any way to obtain name of the current project? RRS feed

  • Question

  • Hello! There's a template which traverses all files in solution and generates helpers for some of them. Currently the bootstrap part looks like

    string projectName = "SomeProject";
    IServiceProvider serviceProvider = (IServiceProvider)this.Host;
    DTE dte = (DTE)serviceProvider.GetService(typeof(DTE));
     
    Project currentProject = dte.Solution.Projects.Cast<Project>().Single(p=>p.Name == projectName);
     
    Visit(currentProject);

    Now I'm need to create reusable template, so, I need a way to obtain the name of the current project without hardcoding it. Any suggestions?

    Thanks!

    Tuesday, June 21, 2011 1:10 AM

All replies

  • Dte.ActiveSolutionProjects should give you what you need.
    Gareth Jones - Developer Architect - T4, UML Designer Extensibility [MSFT]
    Saturday, June 25, 2011 4:50 AM
  • Sadly, it would not. TextTransformation.TransformAllTemplates command and third-party extensions do not select projects before refreshing the templates. On case I'm wrong, I'll recheck it on monday.

    Anyway, thanks!

    Saturday, June 25, 2011 5:50 AM
  • UPD. Yes, these commands do not select appopriate solutions before runnting the transformation. So, the question stays open.
    Monday, June 27, 2011 4:41 AM
  • UP. I'm happy that the topic moved back to the forum I posted it a month ago:) The sad part - there's still no answers.
    Monday, July 18, 2011 2:34 PM
  • In another forum I recently saw something like this:

     

    <#@ template debug="true" hostSpecific="true" #>
    <#@ output extension=".cs" #>
    <#@ Assembly Name="System.Core.dll" #>
    <#@ Assembly Name="System.Windows.Forms.dll" #>
    <#@ import namespace="System" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Diagnostics" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Collections" #>
    <#@ import namespace="System.Collections.Generic" #> 
    
    <#
     var di = new DirectoryInfo(Host.ResolvePath("..\\..")).FullName;
    #>
    
    <#= di #>
    

     


    This code resolves the full path of the folder "..\.." relative to the template.

    May be this might help if your template is at a specific location or subfolder. Otherwise you can recursively look up for the project's root folter containing the .csproj file and then extract the name of the folder or project file. Or more complicated open the .csproj file as XDocument and look up for the project name with XPath or Linq2XML.


    No pressure, no diamonds.
    Monday, July 18, 2011 8:47 PM
  • > This code resolves the full path of the folder "..\.." relative to the template.

    Yes, but

    a) I need to get project, not directory.

    b) Project items may be added as links to the real files placed somewhere else. So, path being relative to the template file may be not in project directory at all.

    Anyway, thanks!
    Tuesday, July 19, 2011 12:19 AM
  • Ok, if the three options above are not good enough, you could create a custom template for a t4 file, may be a tinclude. When the VS creates an item of this template it replaces a placeholder with the project name.
    No pressure, no diamonds.
    Tuesday, July 19, 2011 5:41 AM
  • Ok. What if I'll need to update the template? If I add template as a link, I can just call svn update and refresh all templates.

    It turns out I have to split the template into two parts as recommeded there. Sadly, there's no way to set custom template parameters using the FileProperties window.

    Tuesday, July 19, 2011 8:29 AM
  • Up.   
    Monday, August 29, 2011 8:17 AM
  • I had the same problem and I managed to solve it like this:

    Project FindProject()
    {
        IServiceProvider serviceProvider = (IServiceProvider)Host;
        DTE dte = (DTE)serviceProvider.GetService(typeof(DTE));
        var item = dte.Solution.FindProjectItem(Host.TemplateFile);
        if (item != null && item.ContainingProject != null)
            return item.ContainingProject;
        throw new InvalidOperationException("Can't find project");
    }
    

    I guess the reply comes too late for you, but perhaps it will help others...

    Wednesday, May 1, 2013 10:11 PM
  • I had the same problem and I managed to solve it like this:

    Project FindProject()
    {
        IServiceProvider serviceProvider = (IServiceProvider)Host;
        DTE dte = (DTE)serviceProvider.GetService(typeof(DTE));
        var item = dte.Solution.FindProjectItem(Host.TemplateFile);
        if (item != null && item.ContainingProject != null)
            return item.ContainingProject;
        throw new InvalidOperationException("Can't find project");
    }

    I guess the reply comes too late for you, but perhaps it will help others...

    I have many tt files in many projects with the same name. Eg. my ResourceGenerator.tt included in many projects.
    Friday, July 10, 2020 12:50 PM