Msbuild: PathTooLongException with _GenerateBindingRedirectsIntermediateAppConfig

Created on 3 Mar 2017  路  8Comments  路  Source: dotnet/msbuild

We just hit a PathTooLongException on EF because this variable was producing the following path.

C:\Projects\EntityFrameworktest\Microsoft.EntityFrameworkCore.SqlServer.Design.FunctionalTests\obj\Debug\netcoreapp1.1\Microsoft.EntityFrameworkCore.SqlServer.Design.FunctionalTests.csproj.Microsoft.EntityFrameworkCore.SqlServer.Design.FunctionalTests.dll.config

That filename seems rather excessive. Does it really need both $(MSBuildProjectFile) and $(TargetFileName) in there?

Most helpful comment

If the .exe/.dll name wasn't unique the assembly would collide in the shared obj directory.

Workaround:

<Target Name="WorkaroundAppConfigPathTooLong"
          BeforeTargets="GenerateBindingRedirects">
    <PropertyGroup>
      <_GenerateBindingRedirectsIntermediateAppConfig>$(IntermediateOutputPath)$(TargetFileName).config</_GenerateBindingRedirectsIntermediateAppConfig>
    </PropertyGroup>
  </Target>

produces:

image

All 8 comments

It doesn't seem like it at first glance.

I've been spelunking through history trying to figure out why it's this way, and it seems to have been introduced in dev12 with GenerateBindingRedirects. I suspect it was named this way as a compromise between

  • The standard $(IntermediateOutputPath)$(MSBuildProjectFile)._{filename}_ pattern for project-singleton caches and
  • The standard app-config naming convention of $(TargetFileName).config

This does cause duplication in the standard case, and having a very long project name that's the same as the assembly name is not uncommon.

I think we could change this variable to $(IntermediateOutputPath)$(MSBuildProjectFile).app.config. Anyone have an idea why not?

(Obligatory "the real problem is #53 and then don't worry about this". Obligatory "but we live in the current world".)

Noticed another variant of this - the CLI happily creates the intermediate file with a path too long, but doesn't copy it to the output directory. Desktop .NET returns false for file existence, maybe that has something to do with it.

Why not $(IntermediateOutputPath)$(TargetFileName).config?

That seems like a reasonable option, too. I don't know whether exe-name or project-name is a "more unique" key for those who take the painful road of sharing an obj directory.

If the .exe/.dll name wasn't unique the assembly would collide in the shared obj directory.

Workaround:

<Target Name="WorkaroundAppConfigPathTooLong"
          BeforeTargets="GenerateBindingRedirects">
    <PropertyGroup>
      <_GenerateBindingRedirectsIntermediateAppConfig>$(IntermediateOutputPath)$(TargetFileName).config</_GenerateBindingRedirectsIntermediateAppConfig>
    </PropertyGroup>
  </Target>

produces:

image

@tmat for the time being, we've resorted to shortening our project names. Seems less hacky than changing an internal property.

I'm currently facing the same problem, and blogged about it here - mostly in terms of how I diagnosed it.

This does seem pretty unnecessarily long at the moment.

Tomas' rationale is right. If TargetFileName weren't unique in obj then you'd already be hosed. Can we go with it and get this fixed in 15.5?

Was this page helpful?
0 / 5 - 0 ratings