0

I'm getting this weird error when trying to build my project:

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)

I have no clue what this error means and where to even start. It's a Web API project, and this appears in the Build Results window in Visual Studio when I do a Rebuild on the project.

The error mentions a problem with this condition: '%(FileName)' != 'netstandard' in the .csproj file. But this doesn't appear when doing a search in the .csproj file.

If I do a search in all files within the solution folder, I can find an occurance of it in 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>

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

I also can't find any relevant results if I try to google this error. Does anybody know whats going wrong here?

I'm using Visual Studio Professional 15.6.0. The project targets .net462.

BG100
  • 4,481
  • 2
  • 37
  • 64

1 Answers1

1

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

According to the NuGet document 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.

That means NuGet will import the appropriate .props and .targets files into the project. So when you install the package NETStandard.Library.2.0.1 into your project, the NETStandard.Library.targets file(which in the \build folder in that package) will be imported into the project file, unload your project, edit it, then you will find following code:

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

Now, the .targets file will works as project file.

Just as you think, the reason for this issue should be related to the package NETStandard.Library.2.0.1.

According the MSBuild document MSBuild Batching:

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

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

is not allowed.

So you will get that error

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

To resolve this issue, you can specify the ItemGroup inside custom target:

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

Source: How do you filter an ItemGroup?

Alternatively, you can create a property that stores the value of this custom metadata:

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

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

Source: Using metadata in conditions

Besides, if you can make sure you are not use that .targets file, you can try to remove the <Import Project="..\packages\NETStandard.Library.2.0.1\build\NETStandard.Library.targets" ... /> in the project file.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • 1
    Thanks for your answer. I've tried adding `%(FileName)...` to store the value of the metadata, and this works perfectly. However, it involves editing the `NETStandard.Library.targets` file, which is installed by NuGet in the packages folder, and so may get overwritten if it gets reinstalled, and it's not added to source control. Is there a way to do something similar by only editing the .csproj file? – BG100 Mar 13 '18 at 10:15
  • 1
    @BG100, yes, what you said is right, that .targets file gets overwritten if it gets reinstalled. To resolve this issue, you can overwrite those scripts in your project file .csporj before the end tag ``. Or you can download that package, overwrite the .targets file, then save that package with a custom name, use the custom package instead of the package `NETStandard.Library` – Leo Liu Mar 13 '18 at 15:10
  • Ok, got it. Thanks for your help :) – BG100 Mar 13 '18 at 15:34