VS2022:从类库csproj获取主程序集TargetFramework的可行方案
解决MSBuild读取主程序TargetFramework的问题
原代码直接在PropertyGroup中使用$([System.Xml.XmlDocument]::new().Load(...))的方式是错误的,因为MSBuild属性函数不支持实例化带有文件IO操作的.NET类,这类有副作用的操作必须通过MSBuild内置任务来完成。
解决方案
使用MSBuild内置的<XmlPeek>任务读取主程序csproj文件中的TargetFramework值,再根据该值设置类库的目标框架。
完整代码示例
<!-- 定义目标:在构建准备阶段读取主程序的TargetFramework --> <Target Name="GetMainExecutableTargetFramework" BeforeTargets="PrepareForBuild"> <!-- 检查主程序项目文件是否存在 --> <Error Condition="!Exists('$(MSBuildStartupDirectory)/$(AssemblyName).csproj')" Text="主程序项目文件未找到:$(MSBuildStartupDirectory)/$(AssemblyName).csproj" /> <!-- 读取主程序csproj中的TargetFramework节点值 --> <XmlPeek XmlInputPath="$(MSBuildStartupDirectory)/$(AssemblyName).csproj" Query="/Project/PropertyGroup/TargetFramework/text()"> <Output TaskParameter="Result" PropertyName="MainExecutableTargetFramework" /> </XmlPeek> <!-- 检查是否成功读取到TargetFramework --> <Error Condition=" '$(MainExecutableTargetFramework)' == '' " Text="无法从主程序项目文件中读取TargetFramework节点" /> </Target> <!-- 根据主程序的TargetFramework设置类库的目标框架 --> <PropertyGroup Condition=" '$(MainExecutableTargetFramework)' == 'net7.0-android' "> <TargetFrameworks>net7.0-android</TargetFrameworks> </PropertyGroup>
注意事项
- 路径调整:如果主程序和类库不在同一个启动目录,需要修改
XmlInputPath的路径,比如使用$(SolutionDir)MainApp/MainApp.csproj(假设主程序在解决方案下的MainApp目录)。 - 多框架处理:如果主程序使用的是
TargetFrameworks(复数,多目标框架),需要将Query改为/Project/PropertyGroup/TargetFrameworks/text(),再通过字符串判断是否包含net7.0-android,例如:<PropertyGroup Condition=" '$([System.String]::Copy($(MainExecutableTargetFramework)).Contains("net7.0-android"))' == 'True' "> <TargetFrameworks>net7.0-android</TargetFrameworks> </PropertyGroup> - 执行时机:
BeforeTargets="PrepareForBuild"确保在构建流程早期就读取到值,避免后续步骤无法使用该属性。
内容的提问来源于stack exchange,提问作者tech74
相关产品推荐
相关产品推荐

