Hello,
when calling ArcGIS code from unit tests, I receive the following exception: "System.InvalidOperationException : Invalid ArcGISRuntime deployment folder, missing folder arcgisruntime100.9\client64".
Here are the steps I took / things I already found out to narrow down the problem:
The deployment folder mentioned in the error message is the exact folder where runtimecore.dll etc. are copied to when platform is set to AnyCPU. I guess this is why the AnyCPU configuration works.
For x64, the .dlls are located directly in bin\x64\Debug, but the test runner seems to expect them to be in bin\x64\Debug\arcgisruntime100.9\client64.
I set the option "Processor Architecture for AnyCPU Projects" available in the VS test explorer settings to x64, but that did not help.
My guess is that the xUnit specific VS test runner is somehow still configured as AnyCPU, but I could not find any info on how to change that.
Steps to reproduce:
[Fact]
public void SomeTest()
{
ArcGISTiledLayer currentMapLayer = new ArcGISTiledLayer(new Uri("https://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Imagery/MapServer")) { NoDataTileBehavior = NoDataTileBehavior.UpSample };
}
I know that this might be more a xunit related issue, but I was hoping you could still investigate.
Thanks
The issue is likely that the manage runtime can't find its native libraries if they aren't deployed in the same folder as your executable (which is likely the test runner and not your test library). You can try setting the InstallPath property on test startup to help it find it if you're using .NET Framework (If you one day move to use .NET Core / .NET 5, there's a different way to hint the runtime where native libs are to be loaded from)
Thanks for the quick reply.
Adding the InstallPath as follows did not change anything.
[Fact]
public void SomeTest(){
ArcGISRuntimeEnvironment.InstallPath = Environment.CurrentDirectory;
// Environment.CurrentDirectory = ...\bin\x64\Debug
ArcGISTiledLayer currentMapLayer = new ArcGISTiledLayer(new Uri("https://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Imagery/MapServer")) { NoDataTileBehavior = NoDataTileBehavior.UpSample };
}
What would be the way to do it in .NET 5?
ArcGISRuntimeEnvironment.InstallPath = Environment.CurrentDirectory;
The path should be to where the arcgisruntime100.x folder is, not current directory (we already search current).
With .NET Core 3.1 and .NET 5+ you'd instead use the DllImportResolvers to help hinting at where libraries are located. However this might not be necessary, as these targets uses a built-in way to get the runtimes deployed that .NET Framework doesn't have, so things "might just work". Example:
System.Runtime.InteropServices.NativeLibrary.SetDllImportResolver(typeof(Esri.ArcGISRuntime.ArcGISRuntimeEnvironment).Assembly, new System.Runtime.InteropServices.DllImportResolver(DllImportResolver));
// ...
private static IntPtr runtimeLibPtr = IntPtr.Zero;
private static IntPtr DllImportResolver(string libraryName, Assembly assembly, System.Runtime.InteropServices.DllImportSearchPath? searchPath)
{
if (libraryName == "RuntimeCoreNet.dll")
{
if (runtimeLibPtr == IntPtr.Zero)
{
System.Runtime.InteropServices.NativeLibrary.TryLoad(@$"installpath\client{(Environment.Is64BitProcess ? "64" : "32")}\RuntimeCoreNet.dll", out runtimeLibPtr);
}
return runtimeLibPtr;
}
return IntPtr.Zero;
}
When I call "Environment.CurrentDirectory", it returns the path to the build output directory, which is where the arcgisruntime100.x folder is located. So e.g. ...\bin\x64\debug.
As a workaround, I mirrored the expected folder structure in the source folder and added the missing runtime dlls manually. So in the test project, I created a folder ...\arcgisruntime100.9\client64, added runtimecore.dll, runtimecorenet.dll and runtimecorenet.wpf.dll, and set the build action to Content -> Copy If Newer for those dlls.
Any chance you could share a small simple xunit sample project that uses the runtime and demonstrates the problem? I'd like to see if we can't make this a bit easier, or work with the xunit team if something here is missing.
Thank you! Much appreciated. I'm able to reproduce the issue and will log a bug for this. I think I might know what the problem is. Hopefully we can address this for the next release.