如何让MSBuild将自定义目标生成的文件纳入引用项目的输出中
正确配置MSBuild自定义输出传递到下游引用项目的方案
核心问题原因
你之前的配置失效有两个核心原因:
- Target的
Outputs属性仅用于增量构建的新旧文件判断,不会自动标记为需要传递到下游的项目输出 - 目标仅绑定了
AfterTargets="Build",而MSBuild收集下游传递文件的时机早于Build完成节点,且你使用的AllItemsFullPathWithTargetPath是内部临时项组,不会被下游引用项目的复制逻辑识别
完整配置方案
只需要修改projA的项目配置,不需要调整任何下游引用项目,配置如下:
1. 注册目标到构建和输出收集依赖链
首先在项目的PropertyGroup中添加依赖注册,让MSBuild在收集项目输出前先运行你的tlb生成逻辑:
<PropertyGroup> <GenerateTypeLibOnBuild>true</GenerateTypeLibOnBuild> <!-- 将自定义目标加入构建流程和输出收集流程的依赖链 --> <BuildDependsOn>$(BuildDependsOn);GenerateTypeLibraries</BuildDependsOn> <BuiltProjectOutputGroupDependsOn>$(BuiltProjectOutputGroupDependsOn);GenerateTypeLibraries</BuiltProjectOutputGroupDependsOn> </PropertyGroup>
2. 修改自定义目标,添加输出项注册
调整你的生成目标,生成tlb后将其加入MSBuild专门用于传递下游输出的项组:
<Target Name="GenerateTypeLibraries" Outputs="$(TargetName).tlb" Condition="'$(GenerateTypeLibOnBuild)' == 'true'"> <PropertyGroup> <TlbFile>$(TargetName).tlb</TlbFile> <TlbFullPath>$(TargetDir)$(TlbFile)</TlbFullPath> </PropertyGroup> <Exec Command='"$(MSBuildProjectDirectory)\..\..\MSBuild\Tools\tlbexp.exe" "$(TargetDir)$(TargetFileName)" /out:"$(TlbFullPath)"' /> <!-- 关键配置:标记tlb为项目输出,自动传递到下游引用项目 --> <ItemGroup> <!-- 标记为项目内置输出,下游引用项目会自动识别 --> <BuiltProjectOutputGroupOutput Include="$(TlbFullPath)"> <TargetPath>$(TlbFile)</TargetPath> <IsKeyOutput>False</IsKeyOutput> </BuiltProjectOutputGroupOutput> <!-- 标记为本地复制项,确保当前项目构建时也会正常输出到bin目录 --> <ReferenceCopyLocalPaths Include="$(TlbFullPath)"> <TargetPath>$(TlbFile)</TargetPath> </ReferenceCopyLocalPaths> </ItemGroup> </Target>
批量配置优化
如果你有50个类似的项目,可以把上述配置封装为一个独立的.props属性文件,在每个需要生成tlb的项目开头导入该文件即可,不需要每个项目重复写配置,维护成本极低。
内容的提问来源于stack exchange,提问作者Katie Kilian
相关产品推荐
相关产品推荐

