免责声明:我认为这不是一个好主意,但似乎可以做到。
为了测试这个解决方案,我创建了两个项目。 ConsoleApplication1 和 ClassLibrary1。 ConsoleApplication1 没有对 ClassLibary1 的引用(在 Visual Studio 中可见),但是当从 Visual Studio 构建 ConsoleApplication1 时,它将构建然后将 ClassLibary1.dll 复制到 ConsoleApplication1 的 bin 文件夹中。
要导入目标文件,您将继续将此行添加到要构建未引用项目的项目中。此路径将相对于当前项目,因此在我的情况下,目标文件位于我的解决方案的根目录。确保在 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 行之后添加它,因为 unreferenced.target 依赖于在 Microsoft.CSharp.targets 中设置的目标。
<Import Project="..\unreferenced.target" />
然后您将继续创建一个文件名 unreferenced.target 并将以下内容添加到文件中。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Start another msbuild task to build your unreferenced project -->
<Target Name="BuildBeforeResolveReferences" BeforeTargets="BeforeResolveReferences">
<MSBuild
BuildInParallel="False"
Projects="$(SolutionDir)ClassLibrary1\ClassLibrary1.csproj"
RunEachTargetSeparately="True"
StopOnFirstFailure="False"
UnloadProjectsOnCompletion="False">
</MSBuild>
</Target>
<Target Name="CopyUnreferencedProjectOutput" AfterTargets="Build">
<!-- This item group is here because we do not want it evaluated by msbuild until the ClassLibrary1.csproj has been compiled and its output is in its output directory -->
<ItemGroup>
<!-- Gets a list of all files at the OutputPath that end in .dll if you need the pdbs remove the .dll -->
<!-- To maintain folder structure in the bin folder use <SourceFiles Include="..\ClassLibary1\@(OutputPath)**\*.dll" /> the double ** is a recursive wild card and will look through all directorys -->
<SourceFiles Include="$(MSBuildProjectDirectory)\..\ClassLibrary1\$(OutputPath)*.dll" />
</ItemGroup>
<!-- To make sure the copy maintains folder structure switch it to this copy -->
<!-- <Copy SourceFiles="@(SourceFiles)" DestinationFiles="@(SourceFiles -> '$(MSBuildProjectDirectory)$(OutputPath)%(RecursiveDir)%(Filename)%(Extension)')" /> -->
<Copy SourceFiles="@(SourceFiles)" DestinationFolder="$(MSBuildProjectDirectory)\$(OutputPath)" />
</Target>
<!-- Cleans up all the files when clean is called -->
<Target Name="CleanUnreferenceProjectOutput" BeforeTargets="Clean">
<ItemGroup>
<!-- Removed the .dll from the end of this to clean up the pdbs as well -->
<SourceFiles Include="$(SolutionDir)\ClassLibrary1\$(OutputPath)*" />
<SourceFiles Include="$(SolutionDir)\ConsoleApplication1\$(OutputPath)*.dll" />
</ItemGroup>
<Delete Files="@(SourceFiles)" />
</Target>
</Project>
我认为这是可以做到的最好的。您可以将其扩展为包含未引用但您想要构建的项目列表,但对于此示例,我只是将其保留在一个列表中。
编辑 2:在获得当前解决方案之前,我对在解决程序集之前将引用注入 ProjectReference 项目组进行了广泛的研究。可以这样做,但您必须将属性 BuildInVisualStudio 设置为 false,否则当在 Microsoft.Common.Current.targets 的 ResolveProjectReferences 目标中评估 msbuild 条件时,您将选择仅运行 GetManifest 目标的 MSBuild 任务。我能够构建解决方案,但由于我对将 BuildInVisualStudio 设置为 false 的内容缺乏了解,因此我选择了上述解决方案。我还添加了一个任务来清理移动到 bin 文件夹中的文件,因为 clean 只会清理项目 obj 文件夹中的 {ProjectName}{ProjectExtension}FileListAbsoluteText.txt。
编辑:在对下面的解决方案进行更多研究之后,它只能从命令行工作。我目前正在调查为什么会发生这种情况。