如何通知依赖项目在使用ProjectReference时必须将输出复制到本地?

时间:2014-08-02 06:20:11

标签: visual-studio msbuild

我有两个项目,我们称之为项目A和项目B.

项目A有一个CopyToOutputDirectory内容项,如下所示:

<ItemGroup>
    <Content Include="MyExampleDependency.txt">
        <Link>MyFunOutputLocation\MyExampleDependency.txt</Link>
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
</ItemGroup>

项目B参考项目A:

<ItemGroup>
    <ProjectReference Include="..\..\Shared\Project A.csproj">
        <Project>{My GUID here</Project>
        <Name>Project A</Name>
    </ProjectReference>
</ItemGroup>

当我构建项目B时,将项目A生成的.dll以及此文本文件复制到输出是足够聪明的。也就是说,当我构建项目B时,我最终会得到类似的东西:

  • bin\Project A\Project A.dll
  • bin\Project A\MyFunOutputLocation\MyExampleDependency.txt
  • bin\Project B\Project A.dll
  • bin\Project B\Project B.exe
  • bin\Project B\MyFunOutputLocation\MyExampleDependency.txt

我有一个新的依赖项,我想在项目A中开始生成;例如来自T4变换。这可以是我使用<Exec任务生成的文件,也可以是由某个自定义目标或类似文件生成的文件。例如:

<ItemGroup>
    <Content Include="Foo.tt">
        <Generator>TextTemplatingFileGenerator</Generator>
        <OutputFilePath>$(OutDir)</OutputFilePath>
        <LastGenOutput>Foo.xml</LastGenOutput>
    </Content>
</ItemGroup>

现在,当我建立时,我最终得到这样的东西:

  • bin\Project A\Project A.dll
  • bin\Project A\Foo.xml&lt; - 未复制到Project B!
  • bin\Project A\MyFunOutputLocation\MyExampleDependency.txt
  • bin\Project B\Project A.dll
  • bin\Project B\Project B.exe
  • bin\Project B\MyFunOutputLocation\MyExampleDependency.txt

请注意,Project A.dll生成的生成文件在复制到项目B时不会与该dll一起复制。如何通知项目B它需要从项目A复制此文件(不编辑项目B的.csproj文件)?

1 个答案:

答案 0 :(得分:3)

如果它只是一个设计时Foo.tt输出,那么就像在解决方案资源管理器中扩展它并使用适当的标记Foo.txt一样简单复制到输出目录,如果您更改了扩展名,请记住再次将其标记为“删除”并将其读入丢失CopyToOutputDirectory元数据的itemgoup中。

如果它是一个外部任务,那么您需要在项目A中挂钩延迟事件(因此它不会在加载时污染资源管理器或甚至干净时出错)并将其添加到{{1最好使用通配符或存在条件。请注意,您选择的活动需要在自定义任务之后但在Content之前运行,例如如果您在项目A的_CopyFilesMarkedCopyLocal中创建了一个文件并挂钩到PreBuildEvent它不能在项目B上进行干净构建,那么您必须再次重建它{{1首先运行并且在评估点找不到任何东西。

项目A.csproj

BeforeBuild

修改

请尝试以下操作。

BeforeBuild中定义<Target Name="BeforeBuild"> <ItemGroup> <Content Include="$(OutputPath)\Bar.txt" Condition="Exists('$(OutputPath)\Bar.txt')"> <Link>Bar.txt</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> </Target> 目标,用于延迟/按需包含T4输出。

Project A

你说你正在转换构建,所以在项目的某个地方你有Foo导入来定义<Target Name="Foo"> <ItemGroup> <Content Include="Foo.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> </Target> 目标及其依赖项。

TextTemplating

Transform导入后隐藏其中一个,即<PropertyGroup> <TransformOnBuild>true</TransformOnBuild> </PropertyGroup> <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\TextTemplating\Microsoft.TextTemplating.targets" />

AfterTransform

这将涵盖90%的案例,剩下的9%将直接在Visual Studio .targets中单独构建<PropertyGroup> <AfterTransform>$(AfterTransform);Foo</AfterTransform> </PropertyGroup> 。由于Project BProject A会正常运行但我们需要挂钩Rebuild因为您看到AfterTransform没有执行,因为没有更改和Visual Studio缓存一切。我们在Import上使用BeforeBuild执行此操作。

InitialTargets

最后的1%是当你手动删除Project A并再次构建而不是重建时,但它与删除<Project InitialTargets="Foo" 相同的行为,缓存的VS版本将再次复制它只有.xml本身缺失或不同。