Select to view content in your preferred language

Adding Files to esriAddinX

1652
6
12-06-2019 10:11 AM
JeffBoyton
Emerging Contributor

I have a third party (licensing client) dll I need to include in my Add-In.  How do I make sure this file is included in my Add-Ins esriAddinX file?  It is not a .Net dll so I cannot easily include it as part of my Add-In solution.

0 Kudos
6 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

If you can't add a reference for the 3rd party DLL to your project, you can always add the DLL to your project as an 'existing item' (note: you can do that to any file type you'd like to add to your add-in payload)  Make sure that the DLL's build action is set to 'Content' and 'copy to output directory' is set to 'Copy ...'.  At run time, just before your add-in is executed by Pro, ArcGIS Pro will unzip the content of your add-in package as described here:  https://github.com/esri/arcgis-pro-sdk/wiki/ProConcepts-Advanced-Topics#loading-3rd-party-assembly-r...

If the 3rd party DLL doesn't get loaded in ArcGIS Pro during runtime you can resolve the DLL's path by adding a handler to do so:

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(ResolveProAssemblyPath);
0 Kudos
JeffBoyton
Emerging Contributor

That got me one step closer.  Now the DLL is in the Install directory inside of the esriAddinX file, but ArcPro fails with 'Unable to load DLL'.  I checked the assembly cache and the dll is there as well.  Could you give me a little more detail for how we would force this dll to be resolved?  Thanks!

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Add these lines in your Module class (this constructor should be called first) - rename Module1 to the name of your Module class:

public Module1()
{
    AppDomain currentDomain = AppDomain.CurrentDomain;
    currentDomain.AssemblyResolve += new ResolveEventHandler(ResolveProAssemblyPath);
}

And add this method to the module class:

static System.Reflection.Assembly ResolveProAssemblyPath(object sender, ResolveEventArgs args)
{
    string folderPath = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(System.Reflection.Assembly.GetExecutingAssembly().Location));
    string assemblyPath = Path.Combine(folderPath, new System.Reflection.AssemblyName(args.Name).Name + ".dll");
    if (!File.Exists(assemblyPath)) return null;
    System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(assemblyPath);
    return assembly;
}

Set a breakpoint in the static method to make sure it gets called before your dll is loaded and double check the path.  Needless to say this all depends on the loading method that is used for your 3rd party dll and only works if the load failure event is triggered.

0 Kudos
JeffBoyton
Emerging Contributor

I ended up using SetDllDirectory to augment the DLL search paths with the cache directory so that the existing DllImport directives would find the dll.  This worked just great.  Thanks for all of your help!

Wolf
by Esri Regular Contributor
Esri Regular Contributor

Also some 3rd party libraries provide methods to change load location for any dlls or subprocesses.  For example i wrote a sample using CefSharp which required this initialization code before i was able to use the control:

if (!Cef.IsInitialized)
{
	var settings = new CefSettings()
	{
		//By default CefSharp will use an in-memory cache, you need to specify a Cache Folder to persist data
		CachePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"),
		BrowserSubprocessPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(Assembly.GetExecutingAssembly().Location)), "CefSharp.BrowserSubprocess.exe")
	};

	//Perform dependency check to make sure all relevant resources are in our output directory.
	Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
}
0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Here is a piece of code that helps to resolve the DLL path is needed:

https://github.com/Esri/arcgis-pro-sdk/wiki/ProGuide-content-and-image-resources#images-as-embedded-...

0 Kudos