Runtime: System.IO.Compression.ZipFile missing classes for net46

Created on 13 Apr 2016  路  20Comments  路  Source: dotnet/runtime

Hi there!
Trying to use System.IO.Compression.ZipFile with net46 platform from nuget version 4.0.1-rc3-24013-00 (from myget/dotnet-core feed), and it seems that ZipFile is missing from the assembly for this TFM.
Note that the only valid assembly that contains the class is for dotnet5.4 TFM

Is this a known issue?

area-System.IO.Compression bug

Most helpful comment

This actually looks like a side-effect of shipping a new version of System.IO.Compression out of band.
ResolveAssemblyReferences is not seeing the assembly conflict between the inbox version and the OOB version. As a result you don't have a binding redirect in the built app.config.

If you add the following, it should fix the issue:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.IO.Compression"
                          publicKeyToken="B77A5C561934E089"
                          culture="neutral" />
        <bindingRedirect oldVersion="4.0.0.0"
                         newVersion="4.1.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

/cc @weshaggard @ianhays

All 20 comments

Nothing is missing here. If you open https://dotnet.myget.org/F/dotnet-core/api/v2/package/System.IO.Compression.ZipFile/4.0.1-rc3-24013-00 and examine it's contents:

ref\net46\System.IO.Compression.ZipFile.dll
...
lib\net46\System.IO.Compression.ZipFile.dll

These are facades that type-forward to the inbox implementation in System.IO.Compression.FileSystem.

.class extern forwarder System.IO.Compression.ZipFile
{
  .assembly extern System.IO.Compression.FileSystem
}
.class extern forwarder System.IO.Compression.ZipFileExtensions
{
  .assembly extern System.IO.Compression.FileSystem
}

If you examine the nuspec you'll also see framework references to the inbox assemblies that are referenced by the facade:

    <frameworkAssemblies>
      <frameworkAssembly assemblyName="mscorlib" targetFramework=".NETFramework4.6" />
      <frameworkAssembly assemblyName="System.IO.Compression.FileSystem" targetFramework=".NETFramework4.6" />
    </frameworkAssemblies>

hm, ok, forgot to look for TypeForward indeed they are there. My original problem (and I realized I didn't explain it in my original post, sorry for that), is that at runtime, I got ExtractDirectory method was not found... I will dig why it doesn't work then...

Ok, I don't see exactly why I'm getting this MethodNotFoundException. I can see that the System.IO.Compression.FileSystem assembly is loaded. See the repro attached:

TestZipFile.zip

One thing I noticed is that System.IO.Compression.ZipFile is not targeting net45 platform unlike System.IO.Compression, so if you try to install it in a regular net45 csproj (not using project.json), it will not be possible to install it. So there is still something wrong with the packaging of ZipFile in corefx.

This actually looks like a side-effect of shipping a new version of System.IO.Compression out of band.
ResolveAssemblyReferences is not seeing the assembly conflict between the inbox version and the OOB version. As a result you don't have a binding redirect in the built app.config.

If you add the following, it should fix the issue:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.IO.Compression"
                          publicKeyToken="B77A5C561934E089"
                          culture="neutral" />
        <bindingRedirect oldVersion="4.0.0.0"
                         newVersion="4.1.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

/cc @weshaggard @ianhays

@ericstj did you figure out why RAR didn't auto-generate this?

No, that's why I'm leaving this open. I need to investigate it more to see if we can force it to auto-generate.

I have a handle on why this isn't working. RAR isn't seeing the conflicts between inbox and OOB assemblies so it isn't generating redirects. I put together a package with an assembly that references every inbox contract in order to force the conflicts.

I have a prototype package that fixes this:
https://github.com/ericstj/corefx/commit/dc4758d813aed317d2acc7f90fb51ae6a82c98e3
https://www.myget.org/feed/netcore-package-prototyping/package/nuget/Microsoft.NETCore.Desktop.Compatibility

Right now we're trying to decide if we want to go with this approach: an uber package that forces a conflict with every facade, something added to every package, or attempt a fix to RAR.

The downside of putting something in every package is you end up with ~50 additional files passed to the compiler rather than 1. The downside of trying to fix RAR is that we could only do that in the latest VS, whereas the current fix will work in downlevel VS versions.

@ericstj was there a resolution to this?

Folks hitting it can reference the workaround package. That will force the bindingRedirects to be correctly generated.

We're revamping packaging as part of the next release and hope to better address these types of issues.

Closing this as there is a workaround. Thanks Eric.

I don't think my unsigned workaround package on a myget feed is a sufficient workaround. We should get something more official.

The workaround does not work if the project is packed into a NuGet package.

My setup: dotnet core project with

  "frameworks": {
    "net461": {
      "imports": "dnxcore50"
    },
    "netstandard1.6": {
      "imports": "dnxcore50"
    }
  }

When I used the .dll the net461 build, the workaround worked. When I packed the build into a NuGet package, the problem re-appeared (while the app.config remained unchanged).

@xavierpena we recently stripped out the desktop OOB build for System.IO.Compression so that using the latest packages will get you a stable version of the desktop versions of the library.

using the latest packages will get you a stable version of the desktop versions of the library.

@ianhays If I understand it correctly, it means that using the latest of System.IO.Compression.ZipFile should solve the issue? I am using v4.3.0, which I presumed was the latest (Date Published: Wednesday, November 16, 2016).

I am using v4.3.0, which I presumed was the latest (Date Published: Wednesday, November 16, 2016).

4.3.0 is the latest stable, yeah. That version references a System.IO.Compression that contains the OOB package for desktop (4.3.0).

I was referring to the latest prerelease package on dotnet.myget.org published after the merging of https://github.com/dotnet/corefx/pull/16045. However, I apologize; I spoke too soon and there hasn't been a package push since that change, so there isn't a new (fixed) package available yet. So that's not very helpful for you at the moment, but it will be when it gets pushed.

Closing this as it has been resolved in CoreFX. Just waiting on that new package to be uploaded...

@ianhays Just so you know, despite all my efforts I was unable to make it work in the new VS2017 (no workaround, no nothing). Eagerly waiting for that new package to be uploaded.

I apologize @xavierpena, I misunderstood the effect that removing the OOB package would have on your scenario. I expected that removing the build would cause our packaging to make the net46/net463 binary for any future Compression packages be a pure type-forward to desktop. After talking with @ericstj more in detail, I found that to be incorrect. What actually will happen is that the new packages will just bundle-in the last stable version of the OOB package which was 4.3.0 (the one that is causing you issues).

FWIW, this issue is a part of a class of issues (e.g. https://github.com/dotnet/corefx/issues/9846, https://github.com/dotnet/corefx/issues/17014) that are causing us headaches elsewhere due to requiring manual redirects. I'm re-opening this.

cc: @karelz, @ericstj, @weshaggard

I plan to address the primary cause of this issue in the desktop support package that we create for NETStandard2 : https://github.com/dotnet/standard/issues/274. In that package I'll include a shim that will force RAR to see conflicts between the inbox assemblies and the OOB ones. That package will also effectively eliminate all runtime-only conflicts that were being missed, since it will bring in all the facades to support NS2.0, which will be closure complete for all the implementation assemblies.

I have a commit which fixes this by adding my force-conflict assembly to our netfx support package:
https://github.com/ericstj/corefx/commit/4e42db47fb4998f677347596bf975ac83922fdce

This is waiting for https://github.com/dotnet/corefx/pull/18246 to merge then I'll make it a separate PR.

Was this page helpful?
0 / 5 - 0 ratings