项目构建错误 - 与 NET Standard.Library 2.0.1 有关(我认为!)

Project Build Error - Something to do with NETStandard.Library2.0.1 (I think!)

我在尝试构建我的项目时遇到了这个奇怪的错误:

Error: The reference to the built-in metadata "FileName" at position 1 is not allowed in this condition "'%(FileName)' != 'netstandard'".  C:\github\VS\API\VS.API.Public\VS.API.Public.csproj
 at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args)
 at Microsoft.Build.Evaluation.Parser.Parse(String expression, ParserOptions optionSettings, ElementLocation elementLocation)
 at Microsoft.Build.Evaluation.ConditionEvaluator.EvaluateConditionCollectingConditionedProperties[P,I](String condition, ParserOptions options, Expander`2 expander, ExpanderOptions expanderOptions, Dictionary`2 conditionedPropertiesTable, String evaluationDirectory, ElementLocation elementLocation, ILoggingService loggingServices, BuildEventContext buildEventContext, ProjectRootElementCache projectRootElementCache)
 at Microsoft.Build.Execution.ProjectInstance.EvaluateCondition(String condition)
 at JetBrains.Platform.MsBuild.TaskCommon.ProjectModel.Bindings.AddWildcardItemsFromXml(ProjectRootElement element, Boolean isImported, ProjectInstance projectInstance, List`1 items)
 at JetBrains.Platform.MsBuild.TaskCommon.ProjectModel.Bindings.BindWildcardItems(Project project, ProjectInstance projectInstance)
 at JetBrains.Platform.MsBuild.TaskCommon.ProjectModel.Bindings.Bind(Project project, ProjectInstance projectInstance, List`1 targetErrors, List`1 targetWarnings, Dictionary`2 resultsByTarget)
 at JetBrains.Platform.MsBuild.TaskCommon.ProjectModel.Bindings.Bind(Project project, ProjectInstance projectInstance)
 at JetBrains.Platform.MsBuild.TaskCommon.Build.BuildSessionHost.HandleSubmissionFinished(RdBuildRequest request, ProjectWithEvents projectWithEvents, Boolean succeeded, RdTask`1 rdTask)

我不知道这个错误是什么意思,也不知道从哪里开始。这是一个 Web API 项目,当我对项目进行重建时,它会出现在 Visual Studio 的构建结果 window 中。

错误提到了这种情况的问题:.csproj 文件中的 '%(FileName)' != 'netstandard'。但是在 .csproj 文件中搜索时不会出现这种情况。

如果我搜索解决方案文件夹中的所有文件,我可以在 C:\github\vs\packages\NETStandard.Library.2.0.1\build:

中找到它
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <NETStandardLibraryPackageVersion>2.0.1</NETStandardLibraryPackageVersion>
  </PropertyGroup>

  <ItemGroup Condition="'$(_NetStandardLibraryRefPath)' != ''">
    <Reference Include="$(_NetStandardLibraryRefPath)*.dll">
      <!-- Private = false to make these reference only -->
      <Private>false</Private>
      <!-- hide these from Assemblies view in Solution Explorer, they will be shown under packages -->
      <Visible>false</Visible>
      <Facade Condition="'%(FileName)' != 'netstandard'">true</Facade>
      <NuGetPackageId>NETStandard.Library</NuGetPackageId>
      <NuGetPackageVersion>$(NETStandardLibraryPackageVersion)</NuGetPackageVersion>
    </Reference>
    <ReferenceCopyLocalPaths Condition="'$(_NetStandardLibraryLibPath)' != ''" Include="$(_NetStandardLibraryLibPath)*.dll">
      <Private>false</Private>
      <Facade Condition="'%(FileName)' != 'netstandard'">true</Facade>
      <NuGetPackageId>NETStandard.Library</NuGetPackageId>
      <NuGetPackageVersion>$(NETStandardLibraryPackageVersion)</NuGetPackageVersion>
    </ReferenceCopyLocalPaths>
  </ItemGroup>
</Project>

但我对 .targets 文件的工作原理知之甚少,无法知道如何解决这个问题...通常它可以正常工作。

如果我尝试 google 这个错误,我也找不到任何相关结果。有人知道这里出了什么问题吗?

我正在使用 Visual Studio Professional 15.6.0。该项目针对.net462。

But I don't know enough about how .targets files work to know how to resolve this

根据 NuGet 文档 Creating native packages:

A package may also include targets and props files in \build that NuGet will automatically import into projects that consume the package.

这意味着 NuGet 会将适当的 .props.targets 文件导入到项目中。因此,当您将包 NETStandard.Library.2.0.1 安装到项目中时,NETStandard.Library.targets 文件(位于该包的 \build 文件夹中)将被导入到项目文件中,卸载您的项目,编辑它,然后你会发现下面的代码:

 <Import Project="..\packages\NETStandard.Library.2.0.1\build\NETStandard.Library.targets" Condition="Exists('..\packages\NETStandard.Library.2.0.1\build\NETStandard.Library.targets')" />

现在,.targets 文件将用作项目文件。

和你想的一样,这个问题的原因应该和包NETStandard.Library.2.0.1有关。

根据 MSBuild 文档 MSBuild Batching:

Property functions may not appear within metadata values. For example,

%(Compile.FullPath.Substring(0,3))

is not allowed.

所以你会得到那个错误

the built-in metadata "FileName" at position 1 is not allowed in this condition "'%(FileName)' != 'netstandard'"

要解决此问题,您可以在自定义目标中指定 ItemGroup:

<Target Name="YourCustomName">    
  <ItemGroup Condition="'$(_NetStandardLibraryRefPath)' != ''">
    <Reference Include="$(_NetStandardLibraryRefPath)*.dll">
...
    </Reference>
    <ReferenceCopyLocalPaths Condition="'$(_NetStandardLibraryLibPath)' != ''" Include="$(_NetStandardLibraryLibPath)*.dll">
...
  </ItemGroup>       
<Message Text="@(Reference)"/>
</Target>

来源:How do you filter an ItemGroup?

或者,您可以创建一个 属性 来存储此自定义元数据的值:

<PropertyGroup>
   <FimeName>%(FileName)</FimeName>
</Pro‌​pertyGroup>

<ItemGroup>
   ...
      <Facade Condition="'$(FileName)' != 'netstandard'">true</Facade>
    ...
</ItemGroup>

来源:Using metadata in conditions

此外,如果你能确定你没有使用那个.targets文件,你可以尝试删除项目文件中的<Import Project="..\packages\NETStandard.Library.2.0.1\build\NETStandard.Library.targets" ... />