ImageMagick в функциях Azure не может загрузить собственную библиотеку

Я пытаюсь использовать библиотеку Magick.NET для обработки изображений в Функциях Azure.

Я пробовал тот же код в консольном приложении (.NET Core 3.1), которое работает без проблем. Однако при запуске того же кода в проекте функций Azure я получаю следующую ошибку.

Код:

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, а также с тем, как 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)

Консольная трассировка приложения

Функция App Trace

Я также пробовал установить 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 двоичные файлы, а не только тот, который нам нужен, увеличивая размер финальной сборки.

1 ответ

Решение

ОБНОВИТЬ:

Это может быть ошибка в Microsoft.NET.Sdk.Functions версия 3.0.8. Эти проблемы в репозитории github отслеживают это.

  1. Версия 3.0.8 неправильно размещает папку среды выполнения
  2. Microsoft.Data.SqlClient не поддерживается на этой платформе с Microsoft.NET.Sdk.Functions 3.0.8

Кажется, это происходит только при использовании Microsoft.NET.Sdk.Functions версия 3.0.8который, кажется, только что появился в nuget в пятницу. Вместо этого я перейду на3.0.7.

Или, если вы не хотите переходить на более раннюю версию,

Вы могли бы использовать MagickNET.SetNativeLibraryDirectory как работа вокруг

Другие вопросы по тегам