Déterminer la configuration de la solution (débogage/libération) lors de l'exécution D'un modèle T4

j'ai un modèle T4 qui peut afficher soit du contenu optimisé, soit du contenu standard basé sur un drapeau. Actuellement, je change manuellement le drapeau en fonction de mes besoins.

ce que j'aimerais faire est de mettre le drapeau basé sur la Configuration de la Solution dans Visual Studio. Si cette option est activée en mode Debug, Je produirais du contenu standard. Si cette option est activée, j'optimiserai le contenu. J'ai trouvé une autre question T4 qui semble prometteuse.: modèle de texte T4 - est-il possible d'obtenir les symboles de compilation de l'hôte?

Cependant, dans mon cas, je voudrais faire quelque chose comme ce qui suit:

<#@ template language="C#" hostspecific="True" 
    compilerOptions="/d:$(ConfigurationName)" #>

puisque je peux utiliser $(SolutionDir) dans une directive d'assemblage:

<#@ assembly name="$(SolutionDir)myreference.dll" #>

je pensais que le / d:$(ConfigurationName) me mènerait là où j'avais besoin d'aller, et ensuite je pourrais faire ce qui suit pour mettre mon drapeau:

<#
#if Debug 
 optimize = false;
#else 
 optimize = true;
#endif 
#>

Hélas, cela ne semble pas fonctionner. J'ai aussi essayé d'utiliser:

Host.ResolveParameterValue("-", "-", "ConfigurationName");

aussi en vain. Des idées?

23
t4
demandé sur Community 2011-04-08 03:28:05

2 réponses

a peine ai-je demandé, mais je trouve un extrait au bas de cet article de MSDN qui m'amène où je dois être. La réponse ici est d'utiliser L'interface IServiceProvider pour obtenir le Visual Studio DTE . Voici le code qui est en train de le faire (excuses à l'avance pour le code dur "Debug"):

var serviceProvider = Host as IServiceProvider;
var dte = serviceProvider.GetService(typeof(DTE)) as DTE;
var configName = dte.Solution.SolutionBuild.ActiveConfiguration.Name ;
optimize = (configName != "Debug"); 

mise à JOUR

ce code vérifiera si le la configuration actuelle du projet est optimisée. Il a toujours un nom de propriété codé en dur, mais qui est beaucoup moins susceptible de changer. En outre, l'utilisation du drapeau d'optimisation du projet a beaucoup de sens pour mon scénario (essayer de décider si je dois activer les optimisations dans mon propre code):

var serviceProvider = Host as IServiceProvider;
var dte = serviceProvider.GetService(typeof(EnvDTE.DTE)) as DTE;
config = dte.Solution
            .FindProjectItem(Host.TemplateFile)
            .ContainingProject
            .ConfigurationManager
            .ActiveConfiguration;
foreach(Property prop in config.Properties){
    if (prop.Name == "Optimize"){
        optimize = (bool)prop.Value;
        break;
    }
}
23
répondu Emil Lerch 2017-01-09 15:11:42

pour les personnes qui essaient d'obtenir ce travail à design-time (enregistrer fichier) ainsi que à build-time (F5/F6), deux méthodes sont nécessaires.

Emil décrit le moment de la conception de la méthode. Pour la compilation, vous devez d'abord spécifier un paramètre T4 dans votre fichier de projet:

<ItemGroup>
  <T4ParameterValues Include="BuildConfiguration">
    <Value>$(Configuration)</Value>
    <Visible>false</Visible>    
  </T4ParameterValues>
</ItemGroup>

alors vous devez faire référence à elle au sommet de votre .tt:

<#@ parameter type="System.String" name="BuildConfiguration" #>

et cherchez celui d'entre eux qui se trouve être fourni:

string configurationName = Host.ResolveParameterValue("-", "-", "BuildConfiguration");
if (string.IsNullOrWhiteSpace(configurationName))
{
    var serviceProvider = (IServiceProvider)Host;
    var dte = (DTE)serviceProvider.GetService(typeof(DTE));
    configurationName = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
}

Il est nécessaire d'inclure la logique pour les deux si vous voulez que votre modèle de travail dans les deux scénarios. La méthode du temps de conception ne fonctionne pas au moment de la construction (L'hôte DTE n'est pas là pour fournir la Solution), et la méthode du temps de construction ne fonctionne pas au moment de la conception (MSBuild n'est pas là pour fournir le paramètre).

9
répondu Calvin Fisher 2014-11-26 20:53:30