LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Problem when using a .NET assembly that dynamically loads another assembly

We have implemented a series of VIs that use a number of .NET assemblies. One of these .NET assemblies (call it assembly A) dynamically loads and uses another .NET assembly (assembly B). All assemblies are in the same folder. These VIs are distributed to our customers as components to use in their own VIs.

 

I have discovered that the behaviour of LabView is different depending on whether the top-level VI is run from within a LabView project or not. If the VI is run from a project, then the code works fine. However, if the VI is loaded and run stand-alone, then it gives a .NET exception indicating that the dynamically loaded assembly cannot be found. I have used Process Explorer to see what is happening and can see a difference in behaviour:

  • When run as part of a project, LabView loads the assemblies directly from the installed location.
  • When run as a stand-alone VI, each assembly is loaded from a shadow directory (a different directory for each assembly) under the user's AppData folder. Presumably, as LabView does not know about the dynamic dependency, it has not copied assembly B into the same folder as assembly A. If I manually do this, then the VI runs successfully.

Why does LabView exhibit this difference in behaviour? Is there any way that we can force LabView to load the assemblies directly from their installed folder when running a stand-alone VI? Or alternatively, is there any way to ensure that LabView knows about the dynamic dependency?

 

This is using LabView 2014.

 

Thanks.

0 Kudos
Message 1 of 3
(2,646 Views)

I assume you have read the first few paragraphs of this from the help file: http://zone.ni.com/reference/en-XX/help/371361P-01/lvconcepts/loading_assemblies/

 

One of the many advantages of containers like LabVIEW projects is that you can instruct LabVIEW about other dependencies that it might not know about - for example dynamically loaded assemblies. Running a single VI doesn't give LabVIEW any context so the Fusion loading rules as described above will come into effect and Fusion will be looking at the current CLR Host process requesting the binding - LabVIEW.exe in your Program Files folder. Leaving the binding up to Fusion can also be problematic if you have more than one version of the assembly on disk though it sounds like you don't have this problem (yet).

 

Another way is to add Fusion search paths to LabVIEW.exe.config and rely on Fusion search rules but its not great for your customers plus its pretty inflexible.

 

You could also create a Project Library as a container for all our VIs and assemblies. This will give LabVIEW the context to know that all your assemblies are dependencies and will help with deployment (eg. as a Packed Project Library or Source Distribution, neither of which contain project files). I'm not sure if this will alter Fusion's search paths or not but it is something easy to try.

 

Another approach - you haven't specified how your are dynamically loading the assembly so I assume you are using Assembly.LoadFile(). Rather than relying on Fusions search rules specify the path in the static method call so that it is relative to the currently executing assembly, your Assembly A. You can determine the assembly path of the currently executing assembly and then build off that path to create an absolute path to load from. That is a more robust way of performing the dependency load that is independent of LabVIEW or Fusion search rules. An example is here: https://stackoverflow.com/questions/35316942/loading-a-dll-in-c-sharp-from-a-relative-path

 

Otherwise a code sample would be helpful to try out different behaviour.

0 Kudos
Message 2 of 3
(2,619 Views)

Thanks for the response, tyk007. The problem is definitely related to the Fusion search path, but is more complicated because of the peculiar way that LabVIEW is moving the assemblies on disk. However, I've managed to find a workaround - I use the .NET Assembly and Type classes to get the new location of AssemblyA (where LabVIEW is loading it from), check whether it is the install location and, if not, copy AssemblyB to that location.

0 Kudos
Message 3 of 3
(2,600 Views)