Msbuild: Cannot resolve dll after upgrading to VS2019

Created on 2 May 2019  路  8Comments  路  Source: dotnet/msbuild

Steps to reproduce

SupercalifragilisticexpialidociousLongConsoleApp.zip

Restore packages with e.g.

nuget restore C:\SupercalifragilisticexpialidociousLongConsoleApp\SupercalifragilisticexpialidociousLongConsoleApp.sln

Building with VS 2017 works

& '.\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe' C:\SupercalifragilisticexpialidociousLongConsoleApp\SupercalifragilisticexpialidociousLongConsoleApp.sln

Building with VS 2019 fails

& '.\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe' C:\SupercalifragilisticexpialidociousLongConsoleApp\SupercalifragilisticexpialidociousLongConsoleApp.sln

Expected behavior

Building the solution should still work in VS2019

Actual behavior

VS2019 shows the following warnings/erros:

Error   CS1061  'RetryManager' does not contain a definition for 'GetDefaultAzureStorageRetryPolicy' and no accessible extension method 'GetDefaultAzureStorageRetryPolicy' accepting a first argument of type 'RetryManager' could be found (are you missing a using directive or an assembly reference?)
Warning     The referenced component 'Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling' could not be found.
Warning     The referenced component 'Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.WindowsAzure.Storage' could not be found.
Warning     Could not resolve this reference. Could not locate the assembly "Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.WindowsAzure.Storage, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.

Environment data

msbuild /version output:

Microsoft (R) Build Engine version 16.0.461+g6ff56ef63c for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

16.0.461.62831

OS info:
Windows 10 Version 1809 OS Build 17763.437

Additional info:

From what I could see, the problem is related to resolving the package dlls using HintPath.
When the csproj is located at:
C:\SupercalifragilisticexpialidociousLongConsoleApp\SupercalifragilisticexpialidociousLongConsoleApp
with a HintPath of
..\packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll

the concatenated length is above 260 (or some close number) characters.
For the real solution I was debugging, the solution became compilable once I shortened the name of a folder, such that the concatenated length was less than 260 characters.

Most helpful comment

@mfilippov's #4414 should fix this; that should go out with 16.2 (but we missed preview 3).

All 8 comments

Interesting. Do you have the long-path registry key set in Windows? Details on that are at https://github.com/Microsoft/msbuild/issues/53#issuecomment-459062618.

  • The group policy Enable Win32 long paths is set to not configured
  • The registry key Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled it set to 0

I have reported the same problem on the Visual Studio Developer Community forum in this post https://developercommunity.visualstudio.com/content/problem/526583/change-in-max-allowed-filepath-length-when-referen.html . I have experienced the same, that the location of the .csproj file plays a role, not only the path to the referenced assembly. My scenario is the same, when using a nuget package with the old package.config format, where the hintpath can get pretty long dependent on the package name. As stated in the above forum thread I have also tried enabling the long-path registry and this fixed the problem on Windows 10. But some of our machines are still on Windows 7 where that solution is not possible.

The same problem. Unfortunately, our CI machines are still on Windows 7 and there is no workaround at the moment.
Using bisect I have found the breaking change was likely introduced in #3700.
Seems like something is wrong with cached FileExists.

If that is the breaking change, I see where there is a behavior difference from changing the FileExists cache to use getLastWriteTime() instead of fileExists(). For reference, the fileExists() and getLastWriteTime() delegates propagated to that class via RAR are respectively:
https://github.com/microsoft/msbuild/blob/103f944e00db6622521710026a5e0b451502160a/src/Shared/FileUtilities.cs#L895
https://github.com/microsoft/msbuild/blob/103f944e00db6622521710026a5e0b451502160a/src/Shared/NativeMethodsShared.cs#L965

They both make a call to the same native method to check for file existence; however, the former will attempt to shorten the path if greater than MAX_PATH.

I wonder if all paths here may need a call to AttemptToShortenPath at some point too; I noticed (in both before/after the breaking commit) the methods for retrieving assembly metadata don't shorten the path anywhere, and include calls to getLastWriteTime(). So only shortening the path on FileExists may result in inconsistent results, although it would match the previous behavior.

I confirm that there is problem with compilation of Project which references some DLL dependencies, when combined path (of Project and DLLs) exceeds MAX_PATH 260 chars.

  1. In my setup, we have problematic Project under (96 chars):
    C:\Users\dominikj\ja83\yAaVcJ5C\WdkPBmb9QM03\a7xi4UgAjKkMMEBAT\HEGQLaKcMuEAffV6wT8B46d2pBgpwUzEr
  2. And full path of dependency is (188 chars):
    C:\Users\dominikj\ja83\yAaVcJ5C\BhDztgbAEe\Packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll
  3. Project's csproj have got HintPath for dependency (165 chars):
    ..\..\..\BhDztgbAEe\Packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll
  4. So then, combined path's length is greater than limit (262 chars):
    C:\Users\dominikj\ja83\yAaVcJ5C\WdkPBmb9QM03\a7xi4UgAjKkMMEBAT\HEGQLaKcMuEAffV6wT8B46d2pBgpwUzEr\..\..\..\BhDztgbAEe\Packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll

When I try to compile it by Visual Studio 2019, or explicitly via MSBuild (16.1.76+g14b0a930a7) console execution, I got error: _The type 'ReliableSqlConnection' is defined in an assembly that is not referenced. You must add a reference to assembly 'Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'._

However, when I move my sources under some shorter location (just 3 chars less), or just use previous MSBuild (15.9.21+g9802d43bc3) from VS2017 (via IDE or console), everything compiles fine with my setup.

Thankfully solution presented in https://github.com/microsoft/msbuild/issues/53#issuecomment-459062618 with Enable Win32 long paths solves my issue, but still, it works in previous MSBuild version without any changes.

I think #4414 by @mfilippov is a decent path forward here. @ccastanedaucf, can you take a look at it when you get a chance?

@mfilippov's #4414 should fix this; that should go out with 16.2 (but we missed preview 3).

Was this page helpful?
0 / 5 - 0 ratings