如何在.NET项目间跨csproj引用属性以同步版本?
跨项目同步版本属性的可行方案
直接使用$(LibraryProject.VersionPrefix)这种写法无法生效,因为MSBuild不会自动将引用项目的属性暴露给依赖它的项目。以下是几种实现类库版本同步到其他项目的可靠方案:
方案一:使用Directory.Build.props(推荐,统一管理)
将共享的版本属性抽取到解决方案根目录的Directory.Build.props文件中,所有项目会自动继承这些属性,修改一次即可同步所有项目版本。
1. 创建Directory.Build.props文件
<Project> <PropertyGroup> <MajorVersion>0</MajorVersion> <MinorVersion>1</MinorVersion> <PatchVersion>0</PatchVersion> <VersionPrefix>$(MajorVersion).$(MinorVersion).$(PatchVersion)</VersionPrefix> <Version>$(VersionPrefix)</Version> <AssemblyVersion>$(VersionPrefix)</AssemblyVersion> <FileVersion>$(VersionPrefix)</FileVersion> <Company>Acme, Inc</Company> <Copyright>(C) 2023</Copyright> <Product>My Project</Product> </PropertyGroup> </Project>
2. 简化LibraryProject.csproj
移除重复的共享属性,只保留项目特有的配置:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Library</OutputType> <TargetFramework>net6.0-windows10.0.17763.0</TargetFramework> <ImplicitUsings>disable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> </Project>
3. 简化Exe项目的csproj
同样移除重复属性,保留自身特有配置:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0-windows10.0.17763.0</TargetFramework> <ImplicitUsings>disable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <ProjectReference Include="LibraryProject.csproj" /> </ItemGroup> </Project>
方案二:通过MSBuild任务主动读取类库属性
如果必须从LibraryProject.csproj直接读取属性,可以通过自定义MSBuild目标实现:
1. 修改LibraryProject.csproj,添加属性暴露目标
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Library</OutputType> <TargetFramework>net6.0-windows10.0.17763.0</TargetFramework> <ImplicitUsings>disable</ImplicitUsings> <Nullable>enable</Nullable> <Company>Acme, Inc</Company> <Copyright>(C) 2023</Copyright> <Product>My Project</Product> <MajorVersion>0</MajorVersion> <MinorVersion>1</MinorVersion> <PatchVersion>0</PatchVersion> <VersionPrefix>$(MajorVersion).$(MinorVersion).$(PatchVersion)</VersionPrefix> <Version>$(VersionPrefix)</Version> <AssemblyVersion>$(VersionPrefix)</AssemblyVersion> <FileVersion>$(VersionPrefix)</FileVersion> </PropertyGroup> <!-- 添加目标用于对外暴露属性 --> <Target Name="GetProperty"> <Message Text="$($(PropertyName))" /> <Output TaskParameter="MessageText" PropertyName="OutputProperty" /> </Target> </Project>
2. 修改Exe项目的csproj,获取并应用属性
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0-windows10.0.17763.0</TargetFramework> <ImplicitUsings>disable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <!-- 在构建初始化前获取类库的VersionPrefix --> <Target Name="SyncLibraryVersion" BeforeTargets="InitializeBuild"> <MSBuild Projects="LibraryProject.csproj" Targets="GetProperty" Properties="PropertyName=VersionPrefix"> <Output TaskParameter="TargetOutputs" PropertyName="LibraryVersionPrefix" /> </MSBuild> <!-- 将获取到的版本应用到当前项目 --> <PropertyGroup> <VersionPrefix>$(LibraryVersionPrefix)</VersionPrefix> <Version>$(VersionPrefix)</Version> <AssemblyVersion>$(VersionPrefix)</AssemblyVersion> <FileVersion>$(VersionPrefix)</FileVersion> </PropertyGroup> </Target> <ItemGroup> <ProjectReference Include="LibraryProject.csproj" /> </ItemGroup> </Project>
方案三:读取类库编译后的程序集版本
如果只需要同步编译后的程序集版本(而非项目文件中的VersionPrefix),可以通过项目引用的元数据获取:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0-windows10.0.17763.0</TargetFramework> <ImplicitUsings>disable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <ProjectReference Include="LibraryProject.csproj" /> </ItemGroup> <Target Name="SyncVersionFromAssembly" BeforeTargets="InitializeBuild"> <GetAssemblyIdentity AssemblyFiles="@(ReferencePath)"> <Output TaskParameter="Assemblies" ItemName="LibraryAssembly" /> </GetAssemblyIdentity> <PropertyGroup> <Version>%(LibraryAssembly.Version)</Version> <AssemblyVersion>%(LibraryAssembly.Version)</AssemblyVersion> <FileVersion>%(LibraryAssembly.Version)</FileVersion> </PropertyGroup> </Target> </Project>
总结
- 优先选择方案一,通过
Directory.Build.props统一管理共享属性,维护成本最低,适合多项目版本同步场景。 - 方案二适合必须从特定项目读取属性的场景,但配置相对复杂。
- 方案三仅适用于同步编译后的程序集版本,无需修改类库项目。
内容的提问来源于stack exchange,提问作者Thomas Marschall
相关产品推荐
相关产品推荐

