Правильный способ использования MSBuild Task, который генерирует код с Intellisense
контекст
Для некоторых проектов мы пытались сделать генерацию кода непосредственно из Visual Studio. Основная идея в том, что вы можете создать кучу (.foo
) файлы, и что каждый (.foo
) файл соответствует одному сгенерированному (.foo.cs
) файл.
В основном процесс работает следующим образом:
- Во время сборки все.foo файлы собраны.
- Некоторые преобразования происходят. Обратите внимание, что для некоторых преобразований требуется информация из всех файлов.foo.
- Для каждого
.foo
файл,.foo.cs
файл испускается с частичным классом.
Обычно я бы создал для этого один генератор файлов (пользовательский инструмент) - однако в этом случае я хотел бы знать, что имя файла всегда .foo.cs
и, кажется, нет способа, которым это можно контролировать из одного генератора файлов. Кроме того, тот факт, что для сборки требуется информация из нескольких файлов, заставил меня выбрать альтернативный подход.
Поэтому я создал задачу сборки MS и зарегистрировал ее в 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>
Это прекрасно работает в том смысле, что работает генерация кода и генерирует все необходимые .cs
файлы.
Обратите внимание, что если Intellisense не работает, пока я не нажму "построить" - это нормально.
ситуация
Проблема в том, что Intellisense не работает .foo.cs
файлы, и я ищу способ исправить это.
Я попытался исправить это, изменив .csproj
файл еще больше:
<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" />
Похоже, это работает, в том смысле, что файлы теперь отображаются в обозревателе решений Visual Studio.
Однако я не знаю, как создать это автоматически, и не смог найти ни документации, ни примера об этом. Я предполагаю, что это связано с созданием правильного VSTemplate?
Вопрос
Как правильно решить эту проблему? Например, как я могу убедиться, что сгенерированные файлы отображаются в Visual Studio, чтобы Intellisense мог их забрать?
0 ответов
У меня была аналогичная проблема: у меня есть задача, которая генерирует файл.cs на основе шаблона. Проект нацелен на ядро dotnet 3.1
Сначала я написал
<Target Name="GenerateEnvFiles" BeforeTargets="BeforeBuild;BeforeClean">
Сборка работала, а вот intellisense - нет.
Я проверял разные источники и нашел статью на msdn, в которой говорится:
IntelliSense во время разработки Чтобы получить поддержку IntelliSense в Visual Studio до того, как сборка сгенерирует выходную сборку, должны быть выполнены следующие условия:
Должна быть цель с именем Compile.
Хотя установка BeforeTargets=...;Compile
не сработало, установка CoreCompile вместо этого сработала для меня, и теперь и сборка, и intellisense работают нормально.
Я предполагаю, что у анализатора intellisense есть собственный рабочий процесс, в котором используются другие цели, кроме BeforeBuild. Но я не нашел никаких подробностей о том, какие именно цели он использует (например, из статьи msdn выше, я бы подумал,BeforeTargets="Compile"
должно работать, а пока нет)