corert icon indicating copy to clipboard operation
corert copied to clipboard

How to use the System.IO.Compression namespace ?

Open brunomlopes opened this issue 6 years ago • 12 comments

Say I've got the following core on a .net core console app:

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            using(var stream = File.OpenRead(args[0]))
            using (var compressed = new ZipArchive(stream, ZipArchiveMode.Read))
            {
                foreach (var zipArchiveEntry in compressed.Entries)
                {
                    using (var fileStream = zipArchiveEntry.Open())
                    using (var outputStream = new MemoryStream())
                    {
                        fileStream.CopyTo(outputStream);
                    }

                    Console.WriteLine($"Wrote {zipArchiveEntry.FullName}");
                }
            }
        }

If I compile it with dotnet publish -c Release -r win-x64, and try to run it with CoreRt.TestCompression.exe ..\sample-zip.zip, it fails with

Unhandled Exception: System.IO.Compression.ZLibException: The underlying compression routine could not be loaded correctly. ---> System.DllNotFoundException: Unable to load DLL 'clrcompression.dll': The specified module could not be found.
   at CoreRt.TestCompresssion!<BaseAddress>+0x11d293
   at CoreRt.TestCompresssion!<BaseAddress>+0x11d1b0
   at Interop.zlib.inflateInit2_(Byte*, Int32, Byte*, Int32) + 0x42
   at Interop.zlib.InflateInit2_(ZLibNative.ZStream&, Int32) + 0x49
   at System.IO.Compression.ZLibNative.ZLibStreamHandle.InflateInit2_(Int32) + 0x29
   at System.IO.Compression.Inflater.InflateInit(Int32) + 0x40

From a quick search, this looks like clrcompression.dll is native code that doesn't get pulled in? Is there anything I can do to work past this?

brunomlopes avatar Mar 05 '18 00:03 brunomlopes

We have not done the work to link clrcompression into the final binary.

The workaround is to copy clrcompression.dll next the native .exe. E.g. publish the app as regular standalone app using dotnet.exe" publish -c Release -r win-x64 /p:NativeCompilationDuringPublish=false first, save clrcompression.dll that got published, and then publish it again as native and copy clrcompression saved earlier next to the native .exe.

This workaround won't give you a single file native binary. Is it something that you need to have?

jkotas avatar Mar 05 '18 03:03 jkotas

Thanks, the workaround works.

I'd prefer a single binary, but a binary and a dll is good enough and a large improvement. I mostly wanted to reduce the number of files in the final folder, and take advantage of faster startup.

brunomlopes avatar Mar 06 '18 00:03 brunomlopes

I have run into same issue:

The underlying compression routine could not be loaded correctly.
   at System.IO.Compression.Inflater.InflateInit(Int32) + 0x1ba
   at System.IO.Compression.DeflateStream.InitializeInflater(Stream, Boolean, Int32) + 0x3e
   at System.IO.Compression.ZipArchiveEntry.GetDataDecompressor(Stream) + 0x3d
   at System.IO.Compression.ZipArchiveEntry.OpenInReadMode(Boolean) + 0x86
   at Core2D.Containers.ProjectContainer.ReadProject(ZipArchiveEntry, IFileSystem, IJsonSerializer) + 0x1b
   at Core2D.Containers.ProjectContainer.Open(Stream, IFileSystem, IJsonSerializer) + 0xa6
   at Core2D.Containers.ProjectContainer.Open(String, IFileSystem, IJsonSerializer) + 0x39
   at Core2D.Editor.ProjectEditor.OnOpenProject(String) + 0xfe

Copying the clrcompression.dll dll fixes the issue for now.

wieslawsoltes avatar Apr 22 '18 11:04 wieslawsoltes

The work required for this:

  • Add publishing of clrcompression.lib to corefx. It should be similar to https://github.com/dotnet/corefx/pull/25628
  • Once that is done, modify CoreRT to consume it.

jkotas avatar Apr 23 '18 16:04 jkotas

The recommended workaround isn't working for me. I just get an error message that says System.EntryPointNotFoundException: Unable to find an entry point named 'CompressionNative_DeflateInit2_' in DLL 'clrcompression.dll'.

The DLL in question is labeled as version 4.6.26515.6, if it matters, and dotnet --version reports 2.1.300.

ShayeHorwitz avatar Jun 25 '18 02:06 ShayeHorwitz

clrcompression.dll needs to be in sync with the rest of framework bits. Here is how you can get the right bits manually at the moment:

  • Download https://dotnet.myget.org/F/dotnet-core/api/v2/package/runtime.win-x64.Microsoft.Private.CoreFx.NETCoreApp/4.6.0-preview1-26624-03
  • The good clrcompression.dll is at runtimes\win-x64\native\clrcompression.dll in the .zip file

I am adding the good clrcompression.dll to CoreRT package in #6009. It will make this workaround easier (binplace it from the CoreRT package, no need to fish for the right version).

jkotas avatar Jun 25 '18 03:06 jkotas

The workaround for now is to add this snippet to your .csproj file:

  <Target Name="CopyClrCompressionDll" AfterTargets="Publish">
    <Copy SourceFiles="$(IlcPath)\framework\clrcompression.dll" DestinationFolder="$(PublishDir)" />
  </Target>

jkotas avatar Feb 21 '19 22:02 jkotas

Bumping as I just ran into this issue. Would adding clrcompression.dll as a reference dll solve this issue for a temporary workaround to produce a single binary?

NotoriousRebel avatar Feb 11 '20 16:02 NotoriousRebel

The answer was no image

NotoriousRebel avatar Mar 06 '20 23:03 NotoriousRebel

@brunomlopes have you tried again since the most recent merge?

NotoriousRebel avatar Mar 25 '20 21:03 NotoriousRebel

Not yet, my use case for this has been running ok with the previous workaround, and hadn't had a reason to revisit it.

brunomlopes avatar Mar 25 '20 21:03 brunomlopes

The workaround for now is to add this snippet to your .csproj file:

  <Target Name="CopyClrCompressionDll" AfterTargets="Publish">
    <Copy SourceFiles="$(IlcPath)\framework\clrcompression.dll" DestinationFolder="$(PublishDir)" />
  </Target>

If you are in Linux, the following would be neat:

  <Target Name="CopyClrCompressionDll" AfterTargets="Publish" Condition="'$(OS)' != 'Unix'">
    <Copy SourceFiles="$(IlcPath)\framework\clrcompression.dll" DestinationFolder="$(PublishDir)" />
  </Target>

ryancheung avatar Oct 13 '20 13:10 ryancheung