LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

dll Working folder

HI,

 

I have created a Vi which uses a .NET dll called Msys. For working this dll call check the presence in it’s working folder of other two dll. The problem is that when I run the VI the Msys can’t find the other dlls because it’s workin folder is something like C:\Users\utente\AppData\Local\assembly\dl3\J9YP7R6Y.10N\BGK2BEZ0.D3L\46a55696\00354d28_ba97d901, and not the folder in which the Msys is located. Why LabVIEW change it? In this why my dll will never find what it needs. I don’t get why the VI goes on that path. There is a way to force in which folder the vi has to work, a sort of searching directory as TestStand.

 

Thank you for the help

 

Best Regards,

Zuc

0 Kudos
Message 1 of 15
(1,143 Views)

See How LabVIEW Locates .NET Assemblies and Reference a .NET DLL That Is Not in the GAC or the LabVIEW Application Directory

-------------------------------------------------------
Control Lead | Intelline Inc
0 Kudos
Message 2 of 15
(1,105 Views)

LabVIEW changes nothing on those search paths (other than adding the project directory itself to the search paths for .Net assemblies when a VI is started from inside a project). Everything else is simple Windows search path handling and there is a significant difference between .Net assembly DLLs and classic DLLs.

 

For .Net assemblies only the executable directory and the GAC are normally searched by .Net. As mentioned for VIs executed from within a project, LabVIEW adds the project directory to the according AppContext. You can also add a manifest file to your executable to add additional paths, but .Net is very finicky about what it allows. It only really will let you choose directories that are located underneath the directory where your executable is located. This is for safety reason as .Net wants to prevent the possibility that random (potentially rogue assemblies) can be injected into a process by adding out of tree dependencies.

 

For classic DLLs things are a bit more involved. Here Windows will search for legacy reasons several other locations too, and an application has pretty much no way of changing anything here (Well it can add extra directories to search since Windows 8, but the relevant code in LabVIEW was originally done in Windows 3.1 and I doubt very much that there was a lot changed since. And no there is not a lot to change there, adding random other directories to the search path is something Microsoft discourages strongly as every new location is an additional security risk for code injection attacks). Basically for classic DLLs these directories are searched, and depending on some registry settings and other policy settings in a slightly different order:

 

- if already in memory with the same name, independent of the actual path, and it is not a SxS DLL, simply use that one

- search the directory in which the executable resides that started the current process

- search the System directory

- search the Windows directory

- search the current directory (this is rubbish and can be disabled by certain policies as it has ABSOLUTELY no place in a multitasking GUI application)

- search in every directory listed in the PATH environment variable (don't you like these DOS hacks??)

 

I suspect you mean the current directory when you talk about the working folder. This only works for classic DLLs, .Net rightly has almost completely abandoned the DOS concept of current directory. And it is total rubbish to use for a lot of reasons. First this is a process wide global variable. Your LabVIEW applications current directory is not the same as the Explorer one, or Outlook or whatever other application you have. It is initialized to the same directory as what the executable is located on startup, unless the process creator choose to set a different default directory in the CreateProcess() call. Second it can be randomly changed with explicit API calls by any code in your process. In addition the Windows file dialog will "helpfully" change it to whatever directory it was in if the user dismisses the file selection dialog to select a directory or file!

And there is absolutely no way to safely try to verify that the path is correct and set it differently if it is not, as there is always a window of opportunity for someone (including the file selection dialog) to change it back to whatever between setting it to correct it and hoping to use it when you do something that uses this current directory.

 

The directory a DLL is located in has specifically no special meaning in Windows, unless it is one of the listed directories above. So you can NOT simply put all DLLs in a random directory and hope that one of them will magically resolve to the others if they are dependencies. If you want to do that, the DLL programmer has to explicitly program that, by determining the full path to the current DLL, strip the DLL name and add the new name to that path and then try to load the DLL dynamically himself. Nothing in Windows DLL default handling will do that on its own!

Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 15
(1,089 Views)

HI,

 

I have to study more to understand everything you have wrote, but I can add some details to clarify my situation:

  • Msys Folder
    • Msys.dll
    • Dll for Msys
    • VI Folder
      • VI that call Msys

In this tree and since all the dll paths are seen by the vi (View -> Net Assembly in Memory, in which only the Msys is directly loaded in memory) why when I start the vi my library (Msys) print that its current working folder is C:\Users\utente\AppData\Local\assembly\dl3\J9YP7R6Y.10N\BGK2BEZ0.D3L\46a55696\00354d28_ba97d901

Which I suppose is a VI Assembly Cash since I see a copy of Msys in there?

Since I call the constructor node in the vi and assigned the Msys correct working folder, why is it changed?

 

Best Regards,

Zuc

0 Kudos
Message 4 of 15
(1,076 Views)

@Zuc_Lab wrote:

 

Since I call the constructor node in the vi and assigned the Msys correct working folder, why is it changed?


That's either some .Net magic for whatever reason or something the DLL does itself to extract some (protected?, encoded?) content. LabVIEW certainly is not doing this.

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 15
(1,070 Views)

HI,

 

I don't understand since I have tried all the combination: standalone vi, project vi with dependencies… I can’t figure out why if I assign the dll path to be C:\Automatic\Msys.dll (where the dll is with all it’s dependencies), when I run the vi only the Msys.dll is copied and runned in C:\Users\utente\AppData\Local\assembly\dl3\J9YP7R6Y.10N\BGK2BEZ0.D3L\46a55696\00354d28_ba97d901.

 

I don’t think it’s a .NET problem, or if it is, how I can fix it? In any case why I found a copy of Msys in that folder? And why in BGK2BEZ0.D3L do I find several folders each one containing only one assembly (also the dll used by Msys)?

Sorry for my insistence but I want to understand everything!

 

Best Regards,

Zuc

0 Kudos
Message 6 of 15
(1,065 Views)

Most likely, .Net does not like rogue directories scattered throughout your system and decided to copy the assembly into a private jail to prevent someone else from tinkering with it. UWP (which is entirely based on .Net) does not even allow out of jail directory access without explicit grant to such a directory. Every application is contained in its own private jail safe and only has access to that and its sub-directory and some system resources such as the UWP API. Everything else needs to be specifically granted by the user such as access to Documents, or Photos or similar.

 

It would seem that .Net considers some C:/Automation/ folder as highly unsafe and simply refuses to load the assembly from there directly, copying it instead into a private user folder and redirecting the load from there. Of course it does not know about the other dependencies that your assembly has as they are most likely interfaced through dynamic loading of some sort so .Net can not determine that they are needed and won't copy them along.

 

You have most likely only two options, either move all the DLLs into your actual project folder and reference them from there, or add them to the GAC. The later will however require that they are strongly named and signed.

 

.Net assemblies may seem like the holy grail for interfacing to external code. Easy to interface too because of the build in type library (if it is made correct). However, Microsoft really is trying to thighten security on .Net and discontinuing many rather loose practices since .Net 4.x. And they will push more and more to go UWP all the way, where .Net is the only API that is not only allowed to be called but even the only one really present.

Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 15
(1,030 Views)

Check this Stackoverflow post for a problem similar to yours as well as the found solution and a link to the MSDN page about it:

 

https://stackoverflow.com/questions/8309411/what-is-cache-appdata-local-assembly-dl3

 

This was 11 years ago so it may or may not still work.

 

Something else to try... this 2nd DLL that the first one needs to find, is it also a .NET DLL?  And if so, is it something you can add to your code?  If you can get a constructor node or even just a class constant to point to that second DLL to also make LabVIEW "see" it, even if it's something you don't run (i.e. put it in the False case of a case statement wired to a True constant or something like that), then that might be enough to make it work.  

0 Kudos
Message 8 of 15
(1,014 Views)

What are the permission settings on C:\Automatic, and how are you calling the VI? Does this occur always?

 

Have you tried running your application elevated? Is this 32-bit or 64-bit? Windows version?

 

I'm not sure exactly what's happening here. This sounds suspiciously similar to UAC redirection. In any case, this doesn't sound like something LabVIEW is doing itself to me. If the assembly is being moved to that location, it seems likely that it's Windows doing it.

0 Kudos
Message 9 of 15
(1,006 Views)

HI,

 

thank you for the advice, the others dlls are related to WinSCP end c++ dll.

 

Best Regards,

Zuc

0 Kudos
Message 10 of 15
(974 Views)