We recently experienced an issue after an upgrade from 10.1 to 10.3, whereby our Device Detection service was failing to initialise on start up. Whilst the fix was relatively straight forward, it did take a while to get to the bottom of it, so I thought it might be worth sharing here.
The error we were receiving was:
WARN Could not initialize 51Degrees provider for database E:\our-file-location\App_Data\DeviceDetection\DeviceDetectionDB-230504120740-36DD16688BD86AF61AB647FD289A5797.hash'
Message: Failed to load the Device Detection native library, common causes include:
- Missing dependencies:
o On Windows, the Visual C++ runtime is not installed, see the Visual Studio download page for the latest C++ Redistributable: https://visualstudio.microsoft.com/downloads/
o On Linux, the libatomic shared object is missing. On Debian based distributions, run ‘apt install libatomic1’; on RedHat based distributions, run ‘<yum|dnf> install libatomic’.
- The DLL file was not copied to the output directory during build, refer to the ‘System.DllNotFoundException’ inner exception for the exact library file name.
- The incorrect DLL was copied to the output directory, this maybe be caused by the build chain determining the incorrect platform or the incorrect platform has been specified in the build process. If using the dotnet command, see https://docs.microsoft.com/en-us/dotnet/core/rid-catalog to specify the correct runtime. If using Visual Studio, make sure the selected Platform (x86/x64) matches your environment.
- If building for .NET Framework, the AnyCPU configuration is not supported, make sure to build for the required Platform (x86/x64).
We had come across a similar issue previously and in that situation and it was due to us not having installed the latest Visual C++ runtime (which is handled when you install the prerequisites using SIF). But in this latest issue, we triple checked and all of the prerequisites were correctly installed.
The reason for the failure was that the incorrect version of the FiftyOne.DeviceDetection.Hash.Engine.OnPremise.Native.dll was being added to the solution during build time. All of our machine were operating on 64 bit infrastructure, but the 32 bit version of the binary was somehow being packaged with the project. The error message in the logs does actually point you towards this. However, its sometimes not so straight forward to tell that this is actually happening.
How to tell what version is being used?
To check if a binary is 32 or 64 bit, you can open the DLL in notepad, search for the first occurencce of the letters PE.
- If it is followed by L then it is 32 bit
- If it is followed by d† then it is 64 bit
Would be nice if it just told you in the properties window wouldn’t it… because of this, we made the incorrect assumption that the correct DLLs were being loaded.
When looking at our build properties within the solution, all of our Debug profiles were set to x64, however some of our Release ones were set to AnyCpu. Because of this, at build time the incorrect ones were being added.
You will notice that even in a correctly working solution, that some of the binaries are 32 bit, yet it still loads and works fine. I think the issue only becomes a problem with the “.Native” DLLs. Further information about this can be seen on the 51 dgrees website:
Use the correct version of the native dll. There are multiple versions of the native dll. Unlike .NET/.NET Core, .NET Framework is currently unable to resolve the correct binary at runtime. As a workaround, you’ll need to copy the correct dll from the ‘runtimes’ folder to the root of the ‘bin’ folder. ….https://51degrees.com/documentation/4.4/_info__f_a_qs.html