LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Specify or Set a .NET Assembly (DLL) Call or Search Path for a Built LabVIEW EXE (Executable)

Solved!
Go to solution

I'm not talking about dynamically loading .NET modules, but dynamically loading VI's that use the modules. So we can add the path to a module in a VI with the .NET call, and then dynamically load the VI's that use the module. Since the path was added, LabVIEW might find it.

0 Kudos
Message 11 of 21
(2,064 Views)

@Poolean wrote:

I'm surprised that this is so complicated. I was really expecting and hoping for an INI token! :'(


From my own search recently, it looks like you should be able to do this with the .NET config file for the EXE and setting the probing or codebase elements, but I haven't checked it yet - https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/specify-assembly-location

 

I believe I tried adding the config with the codebase element in the past and it didn't work, but I didn't put too much effort into it at the time, so I might have done it incorrectly, or might have needed to use the probing element. The thing that worked was placing the EXE into the DLL's folder (or the DLLs and all the dependencies into the EXE's folder), which is ugly, but was workable for the specific case I needed this for.


___________________
Try to take over the world!
0 Kudos
Message 12 of 21
(2,060 Views)

Well that might work but remember that the AppDomain.AppendPrivatePath method is not only depreciated but obsoleted. The reason being that if the search path is simply extended after some assemblies are already loaded, this could lead to nasty conflicts where subsequent resolves for assemblies that are already loaded into memory could suddenly point to a different version of that assembly.

But the main assembly that you interface to with a .Net node will be always found by LabVIEW as it is fully referenced by its path (and LabVIEW does update that path when building an executable). The problem are secondary dependencies but they do not always have to be referenced statically. They could be referenced dynamically when the actual object that uses it is instantiated.

And if you use the AppDomain.AssemblyResolve event instead you are technically not adding the path before loading the assembly, but .Net will callback through this event when the assembly is loaded to ask you to provide it with the loacation for the assembly in question. The event handler (a .Net callback VI) will then have to inspect the parameters to see what assembly is requested and see if it can help .Net in finding it.

 

As to adding assemblies to the application config file as a probing path, this is limited by .Net by design to paths (sub directories) residing inside your main applications directory.

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 13 of 21
(2,052 Views)

I did try to do some .Net assembly resolver through the AppDomain.ResolveAssembly event and this is the code I have come up so far. Not really sure how to test it though.

AppDomain.ResolveAssembly CallbackAppDomain.ResolveAssembly CallbackInstall Assembly ResolverInstall Assembly Resolver

Rolf Kalbermatter
My Blog
0 Kudos
Message 14 of 21
(2,045 Views)

@rolfk wrote:

As to adding assemblies to the application config file as a probing path, this is limited by .Net by design to paths (sub directories) residing inside your main applications directory.

 


Ah, yes, that's hiding at the bottom of the documentation:

 


@rolfk The directories specified in privatePath must be subdirectories of the application base directory.

So much for that, then. I'm guessing for my specific case I will probably stay with moving the EXE to the folder of the DLL, as ugly as that is, rather than start playing with dynamic loading of the VIs and the DLLs. Luckily for me, in this case the private DLLs are all from the same folder.


___________________
Try to take over the world!
0 Kudos
Message 15 of 21
(2,035 Views)

It strikes me as a bit of a backwards logic to move the exe to the directory in which the .Net assemblies are located instead of doing the reverse.

 

But not knowing the software in question, there might be a good reason for this. It definitely does not seem to be designed to be called by a third party app at all.

 

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 16 of 21
(2,031 Views)

Not sure, but would a junction or mklink work? So the data directory has a link to the directory of the assemblies? I'd say LabVIEW should look at those directories as well.

 

I agree that moving the exe to a directory would be a bit too pragmatic for most situations.

0 Kudos
Message 17 of 21
(2,025 Views)

It SHOULD work, but unfortunately the junction and symlink business in Windows is still a second class citizen. Not only are the tools to manage them pretty limited but there are also serious reasons to not do it for certain things. For instance relocating your user profile paths through a junction point to another partition for instance, is a pretty sure way to brick your Windows system when you try to upgrade it to a new version.

 

Not sure how that affects continuous updates in Windows 10 under the new Windows as a service paradigma. But upgrading to Windows 7, 8, and 10 from a previous version was in the past not prepared to deal with such a scenario. 

Rolf Kalbermatter
My Blog
0 Kudos
Message 18 of 21
(2,012 Views)

I have created a .NET assembly in Labview. In the code I use another third-party .NET assembly. 

If I call my assembly in i.e. TestStand, I get an error, as the execution comes to the costructor node, which says, the assembly is not found. 

The third party assembly resides in the data subfolder of my assembly...

 

Why is the third party .NET assembly not found?

0 Kudos
Message 19 of 21
(1,156 Views)

.Net has no concept of an assembly directory. The fact that the dependency is located in your data folder inside the folder that your LabVIEW .Net assembly is located is irrelevant here. The AppDomain that resolves your assembly references is created at the moment your .Net process is instantiated (or a non-.Net process initialzes the CLR) and its local search directory is set to the directory where the exe file resides. If your process is a LabVIEW executable it will also add the data folder as extra search path location to the AppDomain but nothing more. If your process is not a LabVIEW executable, it may have its own custom AppDomain initialization but most don't so you are stuck with the default .Net behaviour.

Rolf Kalbermatter
My Blog
0 Kudos
Message 20 of 21
(1,150 Views)