VS Code中.NET Core构建前用MSBuild Target更新版本的问题
解决方案
问题根源
你当前的方法会导致版本滞后,是因为MSBuild在构建启动阶段就已经加载并解析了.csproj的所有属性,在BeforeBuild目标中修改.csproj文件,只会影响下一次构建,当前构建已经读取完属性,不会生效。
最优方案:直接设置MSBuild属性(无需修改.csproj)
不需要修改.csproj文件,而是通过捕获命令输出直接设置MSBuild的版本属性,这样当前构建就能立即使用新的版本号,同时满足你的两个需求:
配置示例
<PropertyGroup> <!-- 保留默认版本作为 fallback --> <VersionPrefix>1.0.20</VersionPrefix> <VersionSuffix>03412bb</VersionSuffix> </PropertyGroup> <Target Name="SetReleaseVersion" Condition="'$(Configuration)' == 'Release' and '$(BuildingProject)' == 'true'" BeforeTargets="GenerateAssemblyInfo"> <!-- 捕获版本前缀的命令输出 --> <Exec Command="your-command-to-get-version-prefix" CaptureOutput="true" ConsoleToMSBuild="true"> <Output TaskParameter="ConsoleOutput" PropertyName="NewVersionPrefix" /> </Exec> <!-- 捕获版本后缀的命令输出 --> <Exec Command="your-command-to-get-version-suffix" CaptureOutput="true" ConsoleToMSBuild="true"> <Output TaskParameter="ConsoleOutput" PropertyName="NewVersionSuffix" /> </Exec> <!-- 更新版本属性,直接用于当前构建 --> <PropertyGroup> <VersionPrefix>$(NewVersionPrefix.Trim())</VersionPrefix> <VersionSuffix>$(NewVersionSuffix.Trim())</VersionSuffix> <!-- 如果需要直接设置完整Version属性,也可以这样写: <Version>$(NewVersionPrefix.Trim()).$(NewVersionSuffix.Trim())</Version> --> </PropertyGroup> </Target>
关键说明
- BeforeTargets选择:
GenerateAssemblyInfo是SDK风格项目生成程序集版本信息的核心目标,在它之前设置版本属性,能确保新版本号被正确嵌入到DLL的Product Version中。如果是非SDK项目,可以改用BeforeTargets="CoreCompile"。 - Condition条件:
'$(Configuration)' == 'Release':确保仅在Release构建时运行。'$(BuildingProject)' == 'true':当增量构建跳过项目时,BuildingProject会被设为false,目标不会执行,满足"仅实际构建时运行"的需求。
- 捕获命令输出:通过
CaptureOutput="true"和ConsoleToMSBuild="true"捕获命令的控制台输出,再用<Output>元素将输出赋值给MSBuild属性,直接用于当前构建。
备选方案:修改.csproj并重新触发构建(不推荐)
如果必须将版本号持久化到.csproj文件中,可以通过递归调用MSBuild实现,但会增加构建时间:
<Target Name="UpdateProjectVersionAndBuild" Condition="'$(Configuration)' == 'Release' and '$(UpdatedVersion)' != 'true'" BeforeTargets="BeforeBuild"> <!-- 执行命令修改.csproj文件 --> <Exec Command="your-command-to-update-csproj" /> <!-- 重新触发构建,标记已更新版本 --> <MSBuild Projects="$(MSBuildProjectFile)" Properties="UpdatedVersion=true;Configuration=$(Configuration)" Targets="Build" /> <!-- 终止当前构建流程 --> <StopBuild /> </Target>
这种方法会先修改.csproj,再启动新的构建流程使用更新后的版本号,避免版本滞后,但不如直接设置属性高效。
内容的提问来源于stack exchange,提问作者Terry
相关产品推荐
相关产品推荐

