System.IO.Compression assembly not resolved
ILSpy version 6.1.0.5902 (release)
Steps to reproduce
- Load ILSpy.exe into itself :)
- Do the "Load Dependencies" action
Error message shown
Not all standard assemblies are resolved
// System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// Assembly reference loading information:
// There were some problems during assembly reference load, see below for more information!
// Error: Could not find reference: System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
The question is why system (.net assembly) was not found by ILSpy 6.1 release build or I"m missing smth?
Full log from IL is as follows:
// Detected Target-Framework-Id: .NETFramework,Version=v4.7.2
// Referenced assemblies (in metadata order):
// DataGridExtensions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=43de855f87de903a
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\DataGridExtensions.dll
// ICSharpCode.AvalonEdit, Version=6.0.1.278, Culture=neutral, PublicKeyToken=9cc39be672370310
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\ICSharpCode.AvalonEdit.dll
// ICSharpCode.Decompiler, Version=6.1.0.5902, Culture=neutral, PublicKeyToken=d4bfe873e7598c49
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\ICSharpCode.Decompiler.dll
// ICSharpCode.TreeView, Version=4.2.0.8752, Culture=neutral, PublicKeyToken=d4bfe873e7598c49
// Assembly reference loading information:
// Info: Success - Found in Assembly List
// Microsoft.VisualStudio.Composition, Version=16.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// Assembly reference loading information:
// Info: Success - Found in Assembly List
// Mono.Cecil, Version=0.10.3.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\Mono.Cecil.dll
// Mono.Cecil.Pdb, Version=0.10.3.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\Mono.Cecil.Pdb.dll
// mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// OSVersionHelper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5b21df349f6c39c3
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\OSVersionHelper.dll
// PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 (unresolved)
// PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 (unresolved)
// System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// System.Collections.Immutable, Version=1.2.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\System.Collections.Immutable.dll
// System.ComponentModel.Composition, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a (unresolved)
// System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// Assembly reference loading information:
// There were some problems during assembly reference load, see below for more information!
// Error: Could not find reference: System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// System.Reflection.Metadata, Version=1.4.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\System.Reflection.Metadata.dll
// System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (unresolved)
// WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 (unresolved)
// Xceed.Wpf.AvalonDock, Version=3.6.1.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4
// Assembly reference loading information:
// Info: Success - Loading from: c:\IL6\Xceed.Wpf.AvalonDock.dll
// kernel32.dll
// contains no metadata
// shell32.dll
// contains no metadata
// shlwapi.dll
// contains no metadata
// user32.dll
// contains no metadata
// Assembly load log including transitive references:
// Microsoft.VisualStudio.Composition, Version=16.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// Info: Success - Found in Assembly List
// ICSharpCode.TreeView, Version=4.2.0.8752, Culture=neutral, PublicKeyToken=d4bfe873e7598c49
// Info: Success - Found in Assembly List
// ICSharpCode.AvalonEdit, Version=6.0.1.278, Culture=neutral, PublicKeyToken=9cc39be672370310
// Info: Success - Loading from: c:\IL6\ICSharpCode.AvalonEdit.dll
// ICSharpCode.Decompiler, Version=6.1.0.5902, Culture=neutral, PublicKeyToken=d4bfe873e7598c49
// Info: Success - Loading from: c:\IL6\ICSharpCode.Decompiler.dll
// System.Reflection.Metadata, Version=1.4.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// Info: Success - Loading from: c:\IL6\System.Reflection.Metadata.dll
// System.Collections.Immutable, Version=1.2.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// Info: Success - Loading from: c:\IL6\System.Collections.Immutable.dll
// Mono.Cecil, Version=0.10.3.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e
// Info: Success - Loading from: c:\IL6\Mono.Cecil.dll
// System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// Error: Could not find reference: System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// Xceed.Wpf.AvalonDock, Version=3.6.1.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4
// Info: Success - Loading from: c:\IL6\Xceed.Wpf.AvalonDock.dll
// DataGridExtensions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=43de855f87de903a
// Info: Success - Loading from: c:\IL6\DataGridExtensions.dll
// OSVersionHelper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5b21df349f6c39c3
// Info: Success - Loading from: c:\IL6\OSVersionHelper.dll
// Mono.Cecil.Pdb, Version=0.10.3.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e
// Info: Success - Loading from: c:\IL6\Mono.Cecil.Pdb.dll
This one is interesting... in fact, there is no System.IO.Compression assembly with version 4.2.0.0, only version 4.0.0.0. This used to work, because we were always falling back to the GAC, when working with assemblies compiled for .NET framework:
https://github.com/icsharpcode/ILSpy/blob/2403548ce3479a7481c866ed17da3b551f0d81bf/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs#L336-L342
4.2.0.0 >= 4.0.0.0, therefore this is skipped and no assembly is found.
.NET really has some strange things going on with respect to assembly versioning...
@siegfriedpammer explanation from Microsoft:
There were some out of band packages for System.IO.Compression released with a higher versions reference assemblies. When supported netstandard 2.0 we had to support such reference versions and that is why VS ship with such higher version number in the ref assemblies. The .NET assembly loader internally handle such higher reference assembly version and map it to the implementation assembly 4.0.0.0.
https://developercommunity.visualstudio.com/t/systemiocompression-in-net-48-version-number-diffe/995459
I don't know if this is only the case for System.IO.Compression or if there are others, I think only a Microsoft developer can tell us that.
I did some asking around, and the conclusion is that the only way to be able to reliably resolve assemblies from the GAC is to directly call fusion.dll.
It's either using fusion.dll or the current method that is not 100% perfect.
This is the answer I got:
there’s a patent https://patents.google.com/patent/US20140337824. yes, this is done for most System.* assemblies (e.g. System.ValueTuple or System.Net.Http). the runtime has a special “unification list”/“unification table” with knowledge of all in-box assemblies, so that any compatible major.minor (ignoring the last 2 digits) reference to a framework assembly will automatically be redirected to the version in the framework. you are able to override the framework unification with your own binding redirects, though
Edit: fusion.dll is not the solution, System.Reflection.Assembly calls clr.dll (which exports the same functions as fusion.dll) and I assume that the unification logic is done in there.
Might a solution be to only look at the major version when resolving framework assemblies from the GAC? E.g. it tries to look for 4.2.0.0, if it cannot be found it uses 4.0.0.0 as fallback? This is of course far from perfect, but I think that is what I will implement in my own project atleast.