我正在尝试使用 Magick.NET 库在 Azure Functions 上进行图像处理。
我在控制台应用程序(.NET Core 3.1)中尝试了相同的代码,它可以正常工作。但是,在 Azure Functions 项目中运行相同的代码时,出现以下错误。
代码:
var image = new MagickImage(File.ReadAllBytes(@"<My Image Path>"));
例外:
System.TypeInitializationException: 'The type initializer for 'NativeMagickSettings' threw an exception.'
堆栈跟踪:
at ImageMagick.MagickSettings.NativeMagickSettings..ctor()
at ImageMagick.MagickSettings..ctor()
at ImageMagick.MagickImage..ctor()
at ImageMagick.MagickImage..ctor(Byte[] data)
at FunctionApp2.Function1.Run(TimerInfo myTimer, ILogger log) <-- My Code
内部异常:
Unable to load DLL 'Magick.Native-Q8-x64.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)
内部异常 StackTrace
at ImageMagick.Environment.NativeMethods.X64.Environment_Initialize()
at ImageMagick.Environment.NativeEnvironment.Initialize()
at ImageMagick.Environment.Initialize()
at ImageMagick.MagickSettings.NativeMagickSettings..cctor()
我相信这是由于 Azure Functions 包的组织方式和 Magick.NET 正在寻找要加载的本机二进制文件的路径。我可以确认本机二进制文件是在\bin\Debug\netcoreapp3.1\runtimes\<platform>\native
构建函数应用程序时编写的。
我已经使用 ProcessMonitor 为每个应用程序跟踪了应用程序,并且可以看到函数应用程序在错误的位置查找。
它看起来在
\bin\Debug\netcoreapp3.1\ bin\ runtimes\[平台]\native
代替
\bin\Debug\netcoreapp3.1\runtimes\[平台]\native
(以下跟踪被过滤为仅显示path contains Magick.Native
和过滤到控制台应用程序 exe 和 func.exe 的进程名称)
我也尝试过设置MagickAnyCPU.CacheDirectory
,Directory.GetCurrentDirectory()
但没有帮助。
更新:
构建后,如果我将\netcoreapp3.1\runtimes
文件夹复制\bin
到此可以解决问题,但是如果有适当的解决方法,我目前不想依赖该技巧。
更新 2:
此问题似乎仅在使用
<TargetFramework>netcoreapp3.1</TargetFramework>
和Microsoft.NET.Sdk.Functions
版本时发生3.0.x
使用旧版本时不会出现。我已经成功使用
<TargetFramework>netcoreapp2.1</TargetFramework>
和Microsoft.NET.Sdk.Functions
版本1.0.x
没有这个问题。
那么,是否有一种解决方法可以让 ImageMagick 从正确的位置加载本机库?
潜在的解决方法是让 msbuildruntimes
在构建完成后复制文件夹。
将以下内容添加到 csproj
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy /Y /E $(OutDir)runtimes\ $(OutDir)bin\runtimes\" />
</Target>
或右键单击项目>属性>构建事件并将上述命令粘贴到post build event command line
这将复制所有的runtimes
二进制文件,而不仅仅是我们想要的,增加最终构建的大小。