我必须创建一个自定义的MSBuild Target,因为我有多个带有命名约定的CS文件,所有文件(大多数是1-3个文件)都必须编译成一个程序集。为简单起见,我们假设每个DLL有1个文件。这意味着:
files/file1.cs
files/file2.cs
files/file3.cs
并且在输出中应该有File1.dll,File2.dll File3.dll
所以我创建了一个自定义的MSBuild目标,如下所示:
<ItemGroup>
<CSFile Include="file\*.cs" Exclude="" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.dll"/>
<Reference Include="..\libs\customdll.dll"/>
</ItemGroup>
<Target Name="CompileFiles" Inputs="@(CSFile)" Outputs="$(OutputPath) (CSFile.Filename).dll" >
<CSC Sources="%(CSFile.Identity)" TargetType="library" OutputAssembly="$(OutputPath)%(CSFile.Filename).dll" References="@(Reference)"/>
</Target>
它在某些方面起作用,但是现在当我想要将一些Nuget包挂钩到它(它与NuGet本身无关,但它在我尝试更改一些引用路径时出现)和
<Reference Include="..\libs\customdll.dll"/>
更改为
<Reference Include="customdll"/>
<HintPath>..\libs\customdll.dll</HintPath>
</Reference>
它根本不起作用。看起来MSBuild没有正确解析引用,只使用&#34; Include&#34;属性。它不会检查HintPaths,系统路径等。此外,当我尝试将DependsOnTargets="ResolveAssemblyReferences"
添加到Target
时,我会在调用CSC
时看到引用中的完整路径(当{ {1}}已更改为@(Reference)
),但令人惊讶的是,某些基本引用(如@(ReferencePath)
或System
等)似乎多次被包含在内,编译器抱怨我必须删除重复项。即使我从System.Core
删除它们,错误仍然是相同的。
所以一般有两种错误。首先,当我不使用来自Microsoft.CSharp中的公共目标的<ItemGroup><Reference>..
目标时,基本上说Metadata file
系统could not be found
,这基本上意味着它无法解析引用,第二个错误是当我使用它并且引用被正确解析时,但是libs以某种方式包含多次并且仍然无法编译。
知道如何解决这个问题吗?或者,如果没有VisualStudio生成的完整工作CSPROJ,我的MSBuild目标应该如何实现每个标准的DLL目标。
我已经尝试过MSBuild工具4.0,12.0。以及.NET4.0 / .NET4.5目标框架的各种组合。
答案 0 :(得分:0)
我想到了三个想法:
1)尝试使用Csc taks中的“AdditionalLibPaths”和“BaseAddress”参数。
2)如果你说@(ReferencePath)
包含重复项 - 请删除它们。但是,在运行目标ResolveAssemblyReferences之后,不是来自Reference
项,而是来自ReferencePath
。
尝试RemoveDuplicates
任务
3)(这将是我的方法)忘记自己运行csc。创建两个单独的文件(Main.proj和FileBuild.proj)并使用标准的着名MSBuld任务。 (我是从头上写的,所以可以在这里找到一些类型:P这只是一个概念)
Main.proj:
<ItemGroup>
<CSFile Include="file\*.cs" />
</ItemGroup>
<Target Name="CompileFiles">
<MSBuild Projects="FileBuild.proj" Properties="CsFile=%(CSFile.Identity)" />
</Target>
FileBuild.proj
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<OutputType>Library</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget>
<OutputPath>bin\</OutputPath>
<AssemblyName>$(CsFile)</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.dll"/>
<Reference Include="..\libs\customdll.dll"/>
</ItemGroup>
<ItemGroup>
<Compile Include="$(CsFile)" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
当然,您必须在FileBuild中设置其他信息(比如将AssemblyName更改为仅包含没有扩展名的文件名),或者如果您确实需要输入/输出,则必须从Main.proj中的MSBuild获取输出。