3 votes

Comment utiliser correctement la tâche MSBuild qui génère du code avec Intellisense ?

Contexte

Depuis quelques projets, nous essayons de faire de la génération de code directement depuis Visual Studio. L'idée de base est que vous pouvez créer un groupe de ( .foo ), et que chaque fichier ( .foo ) correspond à un seul fichier généré ( .foo.cs ).

En gros, le processus fonctionne comme suit :

  1. Pendant la construction, tous les fichiers .foo sont collectés.
  2. Certaines transformations ont lieu. Notez que certaines transformations nécessitent des informations provenant de tous les fichiers .foo.
  3. Pour chaque .foo un fichier .foo.cs est émise avec une classe partielle.

Normalement, j'aurais créé un générateur de fichier unique (outil personnalisé) pour cela - cependant, dans ce cas, j'aimerais savoir que le nom de fichier est toujours .foo.cs et il ne semble pas y avoir de moyen de contrôler cela à partir d'un générateur de fichier unique. En outre, le fait que la construction nécessite des informations provenant de plusieurs fichiers m'a incité à opter pour une autre approche.

J'ai donc créé une tâche MS Build et l'ai enregistrée dans le csproj :

<UsingTask AssemblyFile="C:\Projects\FooTool\bin\Debug\FooBuildTool.dll"
           TaskName="FooBuildTool.FooTool" />
<Target Name="Foo" BeforeTargets="BeforeBuild" 
        Condition="'$(MSBuildProjectExtension)' == '.csproj'">
    <FooTool Language="C#" ProjectFolder="$(ProjectDir)" 
             ProjectName="$(ProjectName)" Sources="@(Foo)">
        <Output ItemName="FooCompile" TaskParameter="ComputedSources" />
    </FooTool>
    <ItemGroup>
        <Compile Include="@(FooCompile->'%(Outputs)')" />
    </ItemGroup>
</Target>

Cela fonctionne bien dans le sens où la génération de code fonctionne et génère tous les éléments requis. .cs des fichiers.

Notez que si Intellisense ne fonctionne pas jusqu'à ce que je clique sur "build", ce n'est pas grave.

Situation

Le problème actuel est que l'Intellisense est cassé pour l'élément .foo.cs et je cherche un moyen de résoudre ce problème.

J'ai essayé de résoudre ce problème en changeant le nom de l'utilisateur. .csproj encore plus :

<Compile Include="Test.foo.cs">
  <AutoGen>True</AutoGen>
  <DesignTime>True</DesignTime>
  <DependentUpon>Test.foo</DependentUpon>
</Compile>

...

<Foo Include="Test.foo" Generator="Foo" LastGenOutput="Test.foo.cs" />

Cela semble fonctionner, dans le sens où les fichiers apparaissent maintenant dans l'explorateur de solutions de Visual Studio.

Cependant, je ne sais pas comment créer cela automatiquement, et je n'ai pas trouvé de documentation ni d'exemple à ce sujet. Je suppose que cela a à voir avec la construction d'un VSTemplate approprié ?

Pregunta

Quelle est la bonne façon de résoudre ce problème ? Par exemple, comment puis-je m'assurer que les fichiers générés apparaissent dans Visual Studio, de sorte qu'Intellisense puisse les détecter ?

1voto

Viktor Arsanov Points 138

J'ai eu un problème similaire : j'ai une tâche qui génère un fichier .cs basé sur un modèle. Le projet vise Dotnet Core 3.1.

J'ai d'abord écrit

<Target Name="GenerateEnvFiles" BeforeTargets="BeforeBuild;BeforeClean">

La construction a fonctionné, mais pas intellisense.

J'ai vérifié différentes sources et j'ai trouvé un article sur msdn où ils disent :

Design-time IntelliSense Pour obtenir la prise en charge d'IntelliSense dans Visual Studio avant qu'une construction ait généré un assemblage de sortie, les conditions suivantes doivent être remplies :

Il doit y avoir une cible nommée Compile.

Bien que l'établissement BeforeTargets=...;Compile n'a pas fonctionné, la mise en place de CoreCompile à la place a fonctionné pour moi et maintenant la construction et l'intellisense fonctionnent bien.

Je suppose que l'analyseur intellisense a son propre flux de travail où d'autres cibles sont utilisées que BeforeBuild. Mais je n'ai pas trouvé de détails sur les cibles exactes qu'il utilise (par exemple, d'après l'article msdn ci-dessus, je pense que BeforeTargets="Compile" devrait fonctionner, alors que ce n'est pas le cas)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X