Azure Functions 上的 ImageMagick 无法加载本机库
ImageMagick on Azure Functions cannot load native library
我正在尝试使用 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 正在寻找要加载的本机二进制文件。我可以确认在构建 Function 应用程序时,本机二进制文件已写入 \bin\Debug\netcoreapp3.1\runtimes\<platform>\native
。
我已经使用 ProcessMonitor 跟踪了每个应用程序的应用程序,并且可以看到 Function 应用程序看起来在错误的位置。
它看起来在
\bin\Debug\netcoreapp3.1\ bin\ runtimes\[platform]\native
而不是
\bin\Debug\netcoreapp3.1\runtimes\[platform]\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 从正确的位置加载本机库?
可能的解决方法 是让 msbuild 在构建完成后复制 runtimes
文件夹。
将以下内容添加到 csproj
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy /Y /E $(OutDir)runtimes\ $(OutDir)bin\runtimes\" />
</Target>
或者右击项目 > 属性 > 构建事件并将上面的命令粘贴到 post build event command line
这将复制所有 runtimes
二进制文件,而不仅仅是我们想要的二进制文件,从而增加最终构建的大小。
更新:
这可能是 Microsoft.NET.Sdk.Functions
版本 3.0.8
中的错误。
github 回购中的这些问题正在跟踪这个。
- Version 3.0.8 places the runtimes folder incorrectly
- Microsoft.Data.SqlClient is not supported on this platform with Microsoft.NET.Sdk.Functions 3.0.8
这似乎只有在使用 Microsoft.NET.Sdk.Functions
版本 3.0.8
时才会发生,该版本似乎只是在周五才出现在 nuget 中。我会降级到 3.0.7
.
或者,如果您不想降级,
You could use MagickNET.SetNativeLibraryDirectory
as a work around
我正在尝试使用 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 正在寻找要加载的本机二进制文件。我可以确认在构建 Function 应用程序时,本机二进制文件已写入 \bin\Debug\netcoreapp3.1\runtimes\<platform>\native
。
我已经使用 ProcessMonitor 跟踪了每个应用程序的应用程序,并且可以看到 Function 应用程序看起来在错误的位置。
它看起来在
\bin\Debug\netcoreapp3.1\ bin\ runtimes\[platform]\native
而不是
\bin\Debug\netcoreapp3.1\runtimes\[platform]\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 从正确的位置加载本机库?
可能的解决方法 是让 msbuild 在构建完成后复制 runtimes
文件夹。
将以下内容添加到 csproj
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy /Y /E $(OutDir)runtimes\ $(OutDir)bin\runtimes\" />
</Target>
或者右击项目 > 属性 > 构建事件并将上面的命令粘贴到 post build event command line
这将复制所有 runtimes
二进制文件,而不仅仅是我们想要的二进制文件,从而增加最终构建的大小。
更新:
这可能是 Microsoft.NET.Sdk.Functions
版本 3.0.8
中的错误。
github 回购中的这些问题正在跟踪这个。
- Version 3.0.8 places the runtimes folder incorrectly
- Microsoft.Data.SqlClient is not supported on this platform with Microsoft.NET.Sdk.Functions 3.0.8
这似乎只有在使用 Microsoft.NET.Sdk.Functions
版本 3.0.8
时才会发生,该版本似乎只是在周五才出现在 nuget 中。我会降级到 3.0.7
.
或者,如果您不想降级,
You could use
MagickNET.SetNativeLibraryDirectory
as a work around