corert
corert copied to clipboard
How to use the System.IO.Compression namespace ?
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?
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?
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.
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.
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.
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.
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).
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>
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?
The answer was no
@brunomlopes have you tried again since the most recent merge?
Not yet, my use case for this has been running ok with the previous workaround, and hadn't had a reason to revisit it.
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>