I have a "Classic Desktop" .NET project which references Microsoft.Build
15.1 from NuGet and System.IO.Compression
/System.IO.Compression.FileSystem
from the .NET SDK / GAC.
I'm trying to upgrade this to Microsoft.Build
15.3.
Microsoft.Build
15.3 introduces a dependency on System.IO.Compression
4.1.2.0. The version of System.IO.Compression
in the .NET Framework is 4.0.0.0.
If I compile like this, I get a warning about being unable to resolve assembly conflicts, but my code works:
warning MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed.
Setting the build log verbosity to Detailed yields this output:
1> There was a conflict between "System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089".
1> "System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" was chosen because it was primary and "System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" was not.
1> References which depend on "System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" [C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.IO.Compression.dll].
1> C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.IO.Compression.dll
1> Project file item includes which caused reference "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.IO.Compression.dll".
1> System.IO.Compression
1> References which depend on "System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" [C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\System.IO.Compression.dll].
1> C:\Temp\CompressionMissingMethod\packages\Microsoft.Build.15.3.409\lib\net46\Microsoft.Build.dll
1> Project file item includes which caused reference "C:\Temp\CompressionMissingMethod\packages\Microsoft.Build.15.3.409\lib\net46\Microsoft.Build.dll".
1> Microsoft.Build, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(1988,5): warning MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed.
I can resolve the warning by replacing the SDK/GAC reference to System.IO.Compression
with a NuGet reference. As soon as I do this, however, code using ZipFile
crashes with a MissingMethodException
when the JIT gets to that method.
Unhandled Exception: System.MissingMethodException: Method not found: 'System.IO.Compression.ZipArchive System.IO.Compression.ZipFile.OpenRead(System.String)'. at CompressionMissingMethod.Program.Main(String[] args)
I've put together a very minimal repro case which illustrates this behaviour (check out the branches).
Is there any way to reference both Microsoft.Build
15.3 and System.IO.Compression
with no errors, warnings, or exceptions?
To fix problem indicated by MSB3277 warning (as well as missing method exception problem) - you need to add binding redirect to your app.config
file, so that all bindings are redirected to the last version (4.1.2.0 in this case):
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
So, install Microsoft.Build 15.3, install System.IO.Compression from nuget (which moves your state to that of MissingMethodException case), then add redirect above and exception will go away and things will work without exceptions or warnings.
Alternative suggested in comments is to update all packages to last versions - this also works because of the same reason - binding redirect. If you update all packages then rebuild - a lot of redirects will be added to your config, including redirect for System.IO.Compression (but to version 4.2.0.0). Note that those redirects will be added not to your app.config but directly to the output YourAppName.exe.config file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With