Magick.NET icon indicating copy to clipboard operation
Magick.NET copied to clipboard

Magick.Native-Q8-x64.dll Access Denied (File Locked)

Open pdhenrique3 opened this issue 2 years ago • 9 comments

Magick.NET version

8.2.1

Environment (Operating system, version and so on)

Windows Server 2016, .NET Framework 4.7.1

Description

I have two WebAPI Applications on the same Server, different IIS Application Pools, Magick-Q8 8.2.1 AnyCPU. Both of them applies Magick on images contained in the Temp File Path of the Server.

Inside this Path, Magick generates a folder, containing this file Magick.Native-Q8-x64.dll which is used.

image image

When the first application starts, success, but the file Magick.Native-Q8-x64.dll get locked by the application, and the second application's requests gets the error:

The type initializer for 'NativeMagickSettings' threw an exception. ---> System.TypeInitializationException: The type initializer for 'X64' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'Magick.Native-Q8-x64.dll': Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

I had to unify both applications under the same Application Pool to make them work, but even if there are no code errors locking the file for any longer than necessary, it happens in some time, and this error could still happen in a much smaller possibility

Steps to Reproduce

In a Microsoft IIS, Two applications using Magick.NET.Core 8.2.1 and Magick.NET-Q8-AnyCPU 8.2.1, each one in your own AppPool

Open a file in the Server's Tem FilePath, perform image resize and compress, save the file

Do this in both applications

pdhenrique3 avatar Feb 01 '24 15:02 pdhenrique3

I would advise you to upgrade to the most recent version. I cannot help you with an older release than the most recent one.

You can use MagickNET.SetNativeLibraryDirectory to control the location of the folder those files are written. You might be lucky and have that available in your version but I would still advise you to upgrade due to security issues.

dlemstra avatar Feb 01 '24 20:02 dlemstra

Something simmilar is happening on 13.7.0. (upgraded from 13.1.3 when building the daily version of our app. It seems it happens randomly. Here is the log from the Jenkins build process. image image The only fix for now seems to be recycling the application pool on IIS.

shanji97 avatar May 28 '24 12:05 shanji97

Your app pool is locking those files. There is not much I can do about that.

dlemstra avatar May 28 '24 12:05 dlemstra

🤔 Ok, so I checked the code and put the magick image objects into a using statement. Currently there are no issues related to the locking of the files.

shanji97 avatar Jun 04 '24 06:06 shanji97

Thanks for coming back and mentioning this tip for future readers. This is probably going to help someone in the future!

dlemstra avatar Jun 04 '24 06:06 dlemstra

So we encountered a bug where presumably IIS is locking the Image Magick DLLs.

URL: our custom
Type: GET
Source: Magick.NET-Q8-AnyCPU
Exception: System.EntryPointNotFoundException: Unable to find an entry point named 'MagickSettings_SetFont' in DLL 'Magick.Native-Q8-x64.dll'.
   at ImageMagick.MagickSettings.NativeMethods.X64.MagickSettings_SetFont(IntPtr Instance, IntPtr value)
   at ImageMagick.MagickSettings.NativeMagickSettings.SetFont(String value)
   at ImageMagick.MagickSettings.CreateNativeInstance(IMagickSettings`1 instance)
   at ImageMagick.MagickImage.NativeMagickImage..ctor(IMagickSettings`1 settings)
   at ImageMagick.MagickImage..ctor()
   at ImageMagick.MagickImage..ctor(Stream stream)
   at Pages_Vlozisce_Attachment.GeneralScaleImage(Byte[] attachmentData, Int32 rotation, Int32 page)
   at Pages_Vlozisce_Attachment.ScaleImage(Byte[] attachmentData, Int32 rotation, Int32 page, MimeType mimeType)
   at Pages_Vlozisce_Attachment.Page_Load(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at Marg.BusinessConnect.Gui.BasePage.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

I checked the DLL with Dependency Walker x64 and every DLL I scanned contained the aforementioned entry point. Since I had another IM related feature request (the support of HEIC and HEIF files - so we had to move to Q16-HDRI), I noticed, that I had trouble to remove the Magick.Native-Q8-x64.dll with the command nant.cmd clean. What worked was to recycle the IIS Application Pool and then the deletion worked perfectly. I the manually changed the DLL on our test server (of course I recycled the Application Pool first) and then the upgrade/replacement of the DLL worked smoothly and no errors are being thrown. Is there any way to track these kinds of DLL locks on a low level?

shanji97 avatar Jul 05 '24 08:07 shanji97

@pdhenrique3 I am using Magick.Net 7.17.0.0 in my application, and met exactly the same issue some days ago. Not sure how the other version does, by reading the source code of the version I'm using, I see SetNativeLibraryDirectory() not really set the directory for extracting and placing the native libary. In fact, the folder in windows temp folder for placing the native libary named CacheDirectory. Finally I resolved the issue by manually setting the CacheDirectory to other place during starting my application. Below code might help someone who met similar issue. I just put the code snippet in my Application_Start() method of Global.asax.cs..

image

wsion avatar Aug 10 '24 07:08 wsion