Unable to load DLL 'libSkiaSharp' when referenced in class library targetting netstandard1.3
Description
SkiaSharp beginner here, using VS2019. I created an ASP.NET WebForms application, targetting .NET Framework 4.6 (=.NETStandard 1.3), and installed SkiaSharp v2.88.7 NuGet package in a class library referenced by the WebForms application, compiling as AnyCPU. On build the LibSkiaSharp.dll is not deployed to any bin folder and on runtime I get the infamous error:
Unable to load DLL 'libSkiaSharp': The specified module could not be found.
I added
<ShouldIncludeNativeSkiaSharp>True</ShouldIncludeNativeSkiaSharp>
<PreferredNativeSkiaSharp>x86</PreferredNativeSkiaSharp>
to all PropertyGroups of both the class library and Webforms application *.csproj files, but it makes no difference. I'm out of ideas... From what I could research:
- #513: AnyCPU should be supported with the snippet above added to csproj;
- #955: C++ VS 2015 dist is statically compiled in since v1.68.x, no need to install it;
- #1726: LibSkiaSharp.dll should be copied without issues for library projects;
I confirmed the same issue happens on version 2.80.0. SkiaSharp v1.68.3 works fine and I do get libSkiaSharp.dll deployed in the bin folder, so for now I will continue using that version.
Code
I created a sample project to reproduce the issue and uploaded it to the following GitHub repository:
https://github.com/lbras/SkiaSharpTestWebFormsNETFramework46
Expected Behavior
LibSkiaSharp.dll should be copied to the application bin folder
Actual Behavior
LibSkiaSharp.dll is not deployed with the application, resulting in runtime errors
Version of SkiaSharp
2.88.3 (Current)
Last Known Good Version of SkiaSharp
1.x (Obsolete)
IDE / Editor
Visual Studio (Windows)
Platform / Operating System
Windows
Platform / Operating System Version
Windows 10
Devices
No response
Relevant Screenshots
No response
Relevant Log Output
[DllNotFoundException: Unable to load DLL 'libSkiaSharp': The specified module could not be found. (Exception from HRESULT: 0x8007007E)]
SkiaSharp.SkiaApi.sk_data_new_empty() +0
SkiaSharp.SKData..cctor() +28
[TypeInitializationException: The type initializer for 'SkiaSharp.SKData' threw an exception.]
SkiaSharp.SKData.Create(Stream stream) +0
SkiaSharp.SKImage.FromEncodedData(Stream data) +33
Imaging.ImageFile.IsValid() in D:\Repos\SkiaSharpTestWebFormsNETFramework46\Imaging\ImageFile.cs:30
SkiaSharpTestWebFormsNETFramework46._Default.Page_Load(Object sender, EventArgs e) in D:\Repos\SkiaSharpTestWebFormsNETFramework46\Web\Default.aspx.cs:21
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +85
System.Web.UI.Control.OnLoad(EventArgs e) +79
System.Web.UI.Control.LoadRecursive() +130
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2852
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
Try updating netframework to latest netframework or dotnet8 so you can use netstandard2.0 at least.
Try updating netframework to latest netframework or dotnet8 so you can use netstandard2.0 at least.
I tried updating my sample project to .NET Framework 4.8 and had no issues, SkiaSharp worked out of the box without having to add <ShouldIncludeNativeSkiaSharp> or <PreferredNativeSkiaSharp> using platform Any CPU. I confirmed the same is true for .NET Framework 4.6.2.
So it is an issue specific for .NET Framework 4.6 / .NETStandard 1.3.
.NET Framework 4.6 is out of support so there is no expectation that this should work or not work. A search for netstandard in the repo indicates that netstandard1.3 has been removed with netstandard2.0 and netstandard2.1 and net462 as current targets, which makes sense.
I do expect it to work because SkiaSharp claims it provides bindings for .NET Standard 1.3:
If this is no longer true, then the above statements should be corrected. I specifically picked SkiaSharp because of .NET Standard 1.3 support.
I expect those references would be removed when the current prerelease gets released. Why would this matter to you? You said you updated your project to netframework 4.8 and there was no problem.
Hi folks, looking at this issue I think the nuget UI and readme may not be the greatest source of how this all works.
The meaning of support for .NET Standard 1.3 really just refers to the API level. There is no real ".NET Standard" app. So you can't "run" it. This just means that if you want to build a .NET Standard dll with SkiaSharp, you can do so.
The other part is the .NET Framework, and that is just supported from 4.6.2 since that is the earliest version that supports .NET Standard 2.0.
I agree this is a bit confusing as you have to know that .NET Standard is not really meant to be used in the way you would expect.
I need to see why I do not copy the native dlls for plain .NET Standard. I am sure there was a reason. If you were to build a net8.0 class library I think it gets copied. So, it may have been that everyone using .NET Standard just used it as a library and had some form of app.
I can relate.
The problem occurs on the line:
var canvas = SKSvgCanvas.Create(SKRect.Create(squareSvgSize, squareSvgSize), stream);
Message: System.TypeInitializationException: 'The type initializer for 'SkiaSharp.SKAbstractManagedWStream' threw an exception.' DllNotFoundException: Unable to load DLL 'libSkiaSharp' or one of its dependencies: The specified module could not be found. (0x8007007E)
Installed libs via nuget: SkiaSharp 2.88.8 SkiaSkarp.Svg 1.60.0
I use .NET 7, Class Library project, AnyCPU (i tried x64 too)
The libSkiaSharp.dll exisits in all subfolders of ...\bin\Debug\net7.0\runtimes\PLATFORMNAME\native but not in: ...\bin\Debug\net7.0\runtimes\win\lib\net7.0
Weird behavior: I have another .NET8 project that is a WebAPI Console Application and it works just fine with Microcharts library that uses SkiaSharp 2.80.2.
Any ideas?