LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Failure to load .NET dll in Labview

Hello

I am writing some code in labview that is using a .NET dll. The dll is part of a larger application that consists of many other dll:s and somewhere along the way it fails to load one. 

 

Most of the dll:s are referenced and are no real problem but one in particular is loaded within the code by path. If this path is set as an absolute path it works, but if its set to a relative path it doesnt. For some odd reason it works when i build the labview application and add all DLL:s. An absolute path isnt an option in the long run as its code used in various applications and for various purpose.

 

The dll works just fine when used in a small Visual Studio test program so there seem to be no problem on the .NET side.

All the DLL:s are located in the same folder, and the labview VI calling the DLL is in that same folder as well. This usually does the trick, but not this time.

 

Anyone who have had a simliar issue?

 

Best Regards,

Nimgaard

0 Kudos
Message 1 of 8
(4,583 Views)

Most likely the relative path uses the Current Path to resolve the given path into a full path to load the DLL from. When a process starts, its current path is set to the directory in which the executable is located. If you create an exe file with all the DLLs in the same directory this will work then.

However several operations inside a Windows application automatically change the current path, including when the file dialog is dismissed with a valid path selected. This of course has happened almost certainly in the LabVIEW IDE when selecting a VI or project to load.

There is no simple solution to that unless you can change the actual code in the DLL that tries to reference the other DLL. Instead of just using an absolute or relative path (absolute is terrible, as it will fail when you move the libraries even one directory up or down, simple relative only works if you can install the DLLs in one of the well known locations of Windows such as the GAC for .Net libraries), you should do something like determining the directory in which the loading DLL is, and then adding the relative path for the to loaded library to it.

Best would be to install the libraries into the system, so they can be found automatically by Windows.

Rolf Kalbermatter
My Blog
Message 2 of 8
(4,570 Views)

How do you set a relative path for the dll? 

Where is the dll placed compared to the exe that you build? 

0 Kudos
Message 3 of 8
(4,561 Views)

@Rolf: That is pretty much what we figured out. Somewhere along the line, something messes up the path and even being in the same directory isnt enough. As you write, absolute path isnt a very good solution and in this case completely unacceptable. We have tried to place the dll in the windows folder in hope that its one of the places that it will search, but it seems it sets a path and sticks with it. Maybe we will just have to live with it, seeing that the build works. Effort vs gain i guess. I have some influence over the dll but not very much as its our customer that develops it.

 

@dkfire: The relative path is set in the C# code structure. It isnt referenced, but rather loaded in the code by its name. Since its supposed to be in the same directory as the calling dll, it is just named. This is probably where something is entered into the path making the code unable to load it.

When i built the exe, it didnt work at first since the supporting dll:s ended up in the data directory. Copying the labview exe into that directory made it work though.

 

Thanks for the input, its a bit tricky and every bit that might set me on the right course is much appreciated. Even if it might be that it isnt easily solved.

0 Kudos
Message 4 of 8
(4,541 Views)

.Net DLLs are NOT searched in the Windows or System directory. Microsoft explicitly wanted to avoid the cluttering of those directories with yet another zillion files.

For .Net DLLs you have the Global Assembly Cache, which is meant to contain all the public .Net assemblies on a system. In addition to that, Windows will search the executable directory, that is where the .exe file for the current process is located. But storing your .Net DLLs in the LabVIEW.exe directory is a bad idea, as it is cluttering a location nobody but NI itself should ever touch and also it is a maintenance nightmare. Once you try to setup another system to develop your application on, it's likely that the person who has to do that task, doesn't know or doesn't remember this requirement and spends hours to rediscover everything you are going through now. An additional directory that LabVIEW adds to the .Net DLL search path seems to be the directory of your project file.

So the best solution would be to install those .Net DLLs into the GAC, but that requires strongly named .Net assemblies which your supplier may not be ready to commit to. The second best solution is to place them all in the same directory where your LabVIEW project file is located from which you do the development and when building the application to make sure the build moves all those DLLs into the executable directory.

 

Of course one other solution would be if your .Net assembly developer would explicitly load the secondary DLL in such a way, that he first tries with simply the assembly name (that will work when the assembly is installed in the GAC or in the executable directory) and when that fails do another attempt where he first determines the directory from the current assembly and then adds the name of the secondary assembly to that path and tries to load it that way. This will allow for the situation where all the assemblies are in the same directory but not in one of the 
"Windows well known assembly directories".

I do this type of explicit secondary DLL loading frequently to gather for various installation scenarios.

Rolf Kalbermatter
My Blog
Message 5 of 8
(4,532 Views)

Interesting discussion!

 

Haven't tried it, but could you get around it by using 'Set Current Directory' (kernel32.dll) before loading the DLL that loads the other DLL by name? Code can be found at http://www.ni.com/example/27706/en/ 

 

Best regards,

 

Leah

Message 6 of 8
(4,523 Views)

It may work, or not! It depends on two things:

 

1) If relative paths are resolved to the current directory or not. For normal DLLs that used to be true until Windows 7, for .Net DLLs it should not be the case. But if the DLL in question does explicit loading, then it can of course implement whatever path resolving it wants to do before attempting to load the library.

2) Extra problem is multithreading! This is a global per process variable. There is no way to guarantee that no other thread is setting this variable back to its own liking between the time you call SetCurrentDirectory() and then use a function that depends on the current directory. So it's very bad practice to use the current directory in a multithreaded application and completely unreliable if you don't control the entire process, which in LabVIEW you definitely don't as you can't look into the source code to determine when LabVIEW might call a system function that inadvertently modifies this global process variable.

Rolf Kalbermatter
My Blog
Message 7 of 8
(4,520 Views)

I have tried most of the solutions offered but cant really get it to work. Once again thank you for all the input, it sure isnt very easy when one cant control all of the parameters involved. Going to keep it as is for the time being so that i can move forward with the project.

0 Kudos
Message 8 of 8
(4,498 Views)