Вы можете сделать, как вы предложили: создать файл .cs
с константой во время сборки.Чтобы обойти потенциальные проблемы с системами контроля версий, не добавляйте этот файл в систему контроля версий и создавайте его в месте, игнорируемом системой контроля версий (например, папки obj\Debug
или obj\Release
).
В MSBuild это можетвыглядит следующим образом:
Добавьте следующее после заключительного элемента «Импорт» в ваш файл CSPROJ.
<PropertyGroup>
<!-- Make sure our file is build on every compile -->
<CompileDependsOn>
_CreateMyFile;
$(CompileDependsOn)
</CompileDependsOn>
</PropertyGroup>
<Target Name="_CreateMyFile">
<!-- Add code to create the file on demand.
You could write a custom task, or execute some external tool.
As an example assume it is created as "$(IntermediateOutputPath)\EnvVars.cs".
Where IntermediateOutputPath expands to "obj\Debug" or "obj\Release", respectively.
Either typically beign ignored by version control systems.
-->
<!-- Add file to files to be compiled. -->
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)\EnvVars.cs"/>
</ItemGroup>
</Target>
Возможно, вы захотите поместить вышеперечисленное в пользовательский файл .proj
,которые вы импортируете в свои файлы CSPROJ.
О, и я не нахожу это вообще безобразным.Лично я использую его для всех видов таких задач, таких как атрибуты версии сборки и т. Д.
Обновление: Для предотвращения вызова цели при каждой сборке (или F5 и т. Д.)Вы можете использовать атрибуты Inputs
и Outputs
элемента Target
.Страница MSDN не слишком полезна, но в основном она работает следующим образом: MSBuild проверит, все ли файлы, указанные в атрибуте Output
, актуальны по сравнению с файлами, указанными в атрибуте Inputs
.
Таким образом, вы можете изменить определение цели следующим образом (элемент PropertyGroup остается прежним и добавляется только для полноты):
<PropertyGroup>
<!-- Make sure our file is build on every compile -->
<CompileDependsOn>
_CreateMyFile;
$(CompileDependsOn)
</CompileDependsOn>
</PropertyGroup>
<Target Name="_CreateMyFile"
Inputs="$(IntermediateOutputPath)\EnvVars.cs"
Outputs="$(IntermediateOutputPath)\EnvVars.cs">
<!-- Create EnvVars.cs file -->
<WriteLinesToFile
File="$(IntermediateOutputPath)\EnvVars.cs"
Lines="namespace Foo {}"
Overwrite="true"
Encoding="Unicode"/>
<!-- Add file to files to be compiled. -->
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)\EnvVars.cs"/>
</ItemGroup>
<!-- Add file to files to be removed on target "clean". -->
<ItemGroup>
<FileWrites Include="$(IntermediateOutputPath)\EnvVars.cs"/>
</ItemGroup>
</Target>
Хитрость в следующем: если EnvVars.cs не существует, он будетбыть создан.Если он существует (тогда), он больше не будет создан, поэтому не форсирует сборку на F5.Тем не менее, мы должны предоставить способ избавиться от файла.Следовательно, добавьте его в FileWrites
ItemGroup, которая содержит файлы, которые будут удалены при вызове «чистых» или «перестроенных» целей (или соответствующих команд меню в Visual Studio).Так что если вы хотите новый файл EnvVars.cs, просто перестройте или очистите.