LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with Executable and .NET DLLs

I have recently noticed different behaviors with LabVIEW and .NET DLLs whether I'm running a VI through a LabVIEW project or if the VI is converted into an executable. In my setup, I have a PPL that contains VIs that use different functions from the DLLs.

 

  • When I have a top level VI inside of a LabVIEW project, everything seems to work as I expect it to. The VI dynamically loads the PPL and is able to successfully make VI calls that are contained in the PPL. All the assemblies are used from the location that I've installed them at.
  • When I convert the same top level VI into an executable, things do not behave the same way as the LabVIEW project example. When I run the executable and I load the PPL, I notice that each .NET DLL is copied over to its own individual AppData folder. When I try to make the same call as in the LabVIEW project example, I get an assembly can't be found error. This is because the DLLs that I reference from my PPL have dependencies on other DLLs and relative directory locations are broken when the DLLs are copied over to individual AppData folders.

 I know one way to resolve this issue is to place the executable inside of the folder that contains the .NET DLLs, but there are 1000+ files in that folder so I'm hoping there's a way to avoid that. Is there anything that I can do to make the executable example behave the same way as the project example?

0 Kudos
Message 1 of 5
(3,665 Views)

You may have come across this KB before. In the past, I've simply made a copy of the DLL and place it in the same folder as my .exe.

 

I have not had much success, but you can also try to register the DLL in the GAC. There should be some guides readily available for this, I've tried something similar as this before.

 

Hope it helps!

 

-Hafiz

0 Kudos
Message 2 of 5
(3,653 Views)

Thanks, Hafiz! If possible, my goal is to find a way to have my executable example behave the same as my project example without an extra steps of manually copying DLLs.

 

I think the source of my issue is that my DLLs are copied to a AppData folder, so if there is a way to prevent that then that should solve my problem.

0 Kudos
Message 3 of 5
(3,599 Views)

If  several PPL share the same dll files, you have to ensure that the relative path from each of the ppls relative to the dll is the same. 

 

The same applies to your executuable. LabVIEW stores the path of the dll file relative. Therefore ensure that the path from which the dll for the ppl is loaded stays relative the same for building the executable.

Message 4 of 5
(3,571 Views)

@aptivo wrote:

If  several PPL share the same dll files, you have to ensure that the relative path from each of the ppls relative to the dll is the same. 

 

The same applies to your executuable. LabVIEW stores the path of the dll file relative. Therefore ensure that the path from which the dll for the ppl is loaded stays relative the same for building the executable.


That is generally good advise but only works for DLLs that your LabVIEW app references directly. For dependencies that are indirect (DLLs referenced by your DLLs) LabVIEW has no knowledge of them and also shouldn't try to have that.

Unless the DLL itself does some special handling of these dependencies the standard Windows search mechanism comes into play.

And here a significant difference exists between standard DLLs and .Net assembly DLLs. While Windows searches quite a few directories for standard DLLs this is usually limited to only just the GAC and the process directory (the directory in which the exe file resides which started the current process) for .Net DLLs. When you work in the IDE in LabVIEW, it will also add the project directory to the .Net AppDomain so that Windows will search there too, but for a built executable, if you can't install the DLL in the GAC you are basically required to put it in the process directory.

 

Basically the rule for such DLLs (and even directly from LabVIEW referenced DLLs if possible) is that they either should be located in the GAC (for .Net DLLs) or the Windows System directory (for normal DLLs) whenever there exists a proper installer for that DLL and its dependencies or in the process directory for private DLLs that you somehow have to put on your target system yourself. While it is allowable to have the directly referenced DLLs moved into the "data" directory as the LabVIEW App Builder by default does, you can't do that for DLLs that LabVIEW doesn't know about and in fact not even for DLLs that you reference both directly from LabVIEW and also are dependencies of other DLLs that you try to load. This is because you have no way to control the order in which LabVIEW will attempt to load DLLs.

 

Assume A.DLL that references B.DLL and you have in your LabVIEW code direct calls to both of these DLLs. When LabVIEW ends up loading A.DLL first, and B.DLL is not in one of the standard Windows search locations, the loading of A.DLL fails. If LabVIEW for some reason decides to try to load B.DLL first all is fine because when it then attempts to load A.DLL Windows will see B.DLL is already loaded and simply link to it, without trying to find it again.

 

This works because LabVIEW makes a distinction between private DLLs and public DLLs. Private DLLs are DLLs that have the full path to the DLL defined in the Call Library Node. The Application Builder will also automatically copy them to target directory (usually the "data" subdirectoy) and update the path in the Call Library Node to point to that location as a relative path. On loading the LabVIEW application LabVIEW will reconstruct the full absolute path to the DLL from that relative path and require Windows to load the DLL from there. Windows will not attempt to search DLLs when you specify a full absolute path but simply fail the load if the DLL can't be loaded from that location. LabVIEW in that case will strip the entire path and just pass the DLL name alone to let Windows search the default locations for the DLL. If that also fails LabVIEW will give you an error that the DLL could not be loaded. There is no indication why the load failed.

If you only specify the DLL name alone without any path in the Call Library Node, the App Builder will consider this DLL as a public DLL and NOT include it into the build. This is very important for any Windows system DLL as you do never want a private copy of such a DLL in your application. Aside from the fact that your Windows license doesn't allow you to distribute its DLLs in any case this is for many of them in fact a sure way to crash your application. These DLLs manage all kind of resources and if there are suddenly two of them loaded into memory on a system they can get into a real fit!

Rolf Kalbermatter
My Blog
Message 5 of 5
(3,561 Views)