Msbuild 为不受支持的平台引发错误

Msbuild 为不受支持的平台引发错误,msbuild,Msbuild,我正在创建一个自定义MSBuild脚本,该脚本打算导入到多个C#项目中。脚本基于平台属性添加了几个要复制的属性、引用和文件,以使最终输出能够利用一组本机二进制文件。换句话说,它根据平台选择正确的本机二进制文件集和相关数据 我目前正在做这样的事情: <PropertyGroup Condition="'$(Platform)' == 'x86'"> <bin1>..\..\lib\mybinaries\x86\bin1.dll</bin1> <bi

我正在创建一个自定义MSBuild脚本,该脚本打算导入到多个C#项目中。脚本基于
平台
属性添加了几个要复制的属性、引用和文件,以使最终输出能够利用一组本机二进制文件。换句话说,它根据平台选择正确的本机二进制文件集和相关数据

我目前正在做这样的事情:

<PropertyGroup Condition="'$(Platform)' == 'x86'">
  <bin1>..\..\lib\mybinaries\x86\bin1.dll</bin1>
  <bin2>..\..\lib\mybinaries\x86\bin2.dll</bin2>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'x64'">
  <bin1>..\..\lib\mybinaries\x64\bin1.dll</bin1>
  <bin2>..\..\lib\mybinaries\x64\bin2.dll</bin2>
</PropertyGroup>

<ItemGroup>
  <Reference Include="bin2.dll">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>$(bin2)</HintPath>
    <Private>True</Private>
  </Reference>
</ItemGroup>
<ItemGroup>
  <None Include="$(bin1)">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>
</ItemGroup>

..\..\lib\mybinaries\x86\bin1.dll
..\..\lib\mybinaries\x86\bin2.dll
..\..\lib\mybinaries\x64\bin1.dll
..\..\lib\mybinaries\x64\bin2.dll
假的
$(bin2)
真的
总是
当使用不支持的平台(如任何CPU)构建项目时,我希望该构建引发错误。我该怎么做

我查看了是否有一种方法可以在构建目标之外引发错误,但我没有找到一种方法。即使我真的找到了一个,我也会担心如果开发人员以某种方式让他们的系统选择了一个不受支持的平台会发生什么。(例如Visual Studio可能会开始拒绝打开项目。)

我可以在构建之前覆盖
目标,但如果导入此文件的C#项目随后覆盖该目标本身,则会出现故障。(或者我的将覆盖它们,具体取决于导入的顺序和导入的顺序)在这种情况下,不会出现错误。这使得它相当脆弱,不太坚固


我如何才能以用户不太可能破坏它的方式实现这一点?或者,有没有一种完全不同的替代方法可以让我有条件地包含二进制文件?

我会使用带有错误任务的目标。但是,如果您想要避免自定义目标,那么如果您只是定义了一个肯定会失败的路径,那么您可以使用肮脏的技巧使构建突破属性

可能是这样的:

<PropertyGroup Condition="'$(Platform)' == 'x86'">
  <bin1>..\..\lib\mybinaries\x86\bin1.dll</bin1>
  <bin2>..\..\lib\mybinaries\x86\bin2.dll</bin2>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'x64'">
  <bin1>..\..\lib\mybinaries\x64\bin1.dll</bin1>
  <bin2>..\..\lib\mybinaries\x64\bin2.dll</bin2>
</PropertyGroup>
<PropertyGroup Condition="'$(bin1)' == ''">
  <bin1>ERROR: platform '$(Platform)' is not supported, please set it to x86 or x64</bin1>
</PropertyGroup>

..\..\lib\mybinaries\x86\bin1.dll
..\..\lib\mybinaries\x86\bin2.dll
..\..\lib\mybinaries\x64\bin1.dll
..\..\lib\mybinaries\x64\bin2.dll
错误:不支持平台“$(平台)”,请将其设置为x86或x64
生成将失败,因为这不是一个有效的路径,虽然生成日志会令人困惑,但它会在文件“未找到”中包含此清除消息。:)


同样,我建议定义一个目标…

一种惯用的方法是使用的
BeforeTargets
属性,或者使用的
InitialTargets
属性。因此,您可以编写一个具有所有所需逻辑的自定义目标,然后自动调用它。这也使得用户很难打破它

如果您使用BeforeTargets,您将希望找到一个在构建早期被调用的目标,并且更适合于构建和清理。要想知道使用什么,最简单的方法是使用诊断日志(命令行上的
msbuild/v:d myproject
)构建项目。然后你会发现你不是唯一一个想检查平台有效性的人:C++项目的第一个目标是微软自己的“检查”无效配置和平台。所以如果你使用

<Target Name="PlatformCheck" BeforeTargets="_CheckForInvalidConfigurationAndPlatform">
  <Error Text="Bad Platform" Condition="'$(bin1)' == ''"/>
</Target>

那么PlatformCheck将是最早被调用的目标之一

或者如果你更喜欢另一种方式,那就是

<Project ToolsVersion="4.0" xmlns="..." InitialTargets="PlatformCheck">


也许您正在寻找类似
的东西?它将在生成之前运行,并使用内置的msbuild功能和自定义名称,因此更难重写。可能有更好的目标可以使用,例如“PrepareBuild”之类的,但我不知道这些目标是什么。@stijn我没有意识到这样可以使构建依赖于自定义任务。如果您可以将其转换为答案,我将接受。可以在此处找到新版本MSBuild的任务列表:。我最终使用了
AssignProjectConfiguration
。试图依赖
构建
的过程太晚了;在此之前,您可能会遇到缺少DLL的错误。