LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

What setting to set to stop .NET dll being copied to build folder

Solved!
Go to solution

@cbutcher wrote:

Ah. Found the quote button again 🙂


You're not alone.

0 Kudos
Message 21 of 32
(989 Views)

as to that side effect, I'd imagined that the OP would install the DLLs into some shared folder (e.g. C:\MyAwesomeDLLs\") and that each PPL would just overwrite the previously installed version with the newly installed version.

Wouldn't that work/be what was needed?

 

Potentially it would make a mess of versioning... but that could probably be worked around using versioned directories and symbolic links/junction points, if needed (as is common for some libraries on Linux systems).


.Net tried to do away with the so called DLL hell by significantly simplifying the way applications would use assemblies (which are basically still a form of DLL, though not with the same executable format as standard PE DLLs).

 

They defined two major locations an assembly can be located at, the GAC which is a shared machine global (configurable per user) repository of assemblies and the root directory for the current process. Anything else is considered custom configuration that a process can choose to implement for instance for a plugin system or similar but definitely not something Windows would support out of the box.

In order for an assembly to be copied to the GAC it needs to be strongly named (meaning it needs to have a valid versioning scheme) and might in Windows 10 also require a signing with a certificate but I'm not sure about that. It would make sense to have that as an additional requirement nowadays.

 

Your solution to copy the DLL into a specific global folder other than the GAC is basically a violation of this basic .Net principle. It is most likely inspired by the old habit of defining such a folder and adding its location to the PATH environment variable for Windows to pick up a normal DLL in that directory. And this habit, in addition to polluting the PATH variable which has actually a very real maximum length of about 1000 characters only and which can cause very nasty problems in Windows  once that limit is surpassed, it also is one contributing factor to DLL hell. Of course DLL hell is also made worse by the common habit of users googling a specific problem with some DLLs and blindly following (the very common and usually bad advice in online posts) to download said DLL from some more or less funky site and drop it somewhere on their computer.

Rolf Kalbermatter
My Blog
Message 22 of 32
(984 Views)

From LabVIEW though, when building a packed library, there could be an option to specify if the dll should be copied with the library or not.

 

If the packed library uses a project central dll (one that is always available in the project anyway, or used in several libraries) is a different situation than a (more typical) library wrapping around a dll. The first use case isn't really supported right now, and an optional copy of the dll would fix that.

0 Kudos
Message 23 of 32
(979 Views)

wiebe@CARYA wrote:

From LabVIEW though, when building a packed library, there could be an option to specify if the dll should be copied with the library or not.

 

If the packed library uses a project central dll (one that is always available in the project anyway, or used in several libraries) is a different situation than a (more typical) library wrapping around a dll. The first use case isn't really supported right now, and an optional copy of the dll would fix that.


There is a fundamental problem with this. The compiled VIs in the packed library need to know the location of the assembly if it is not located in the GAC or the process root directory. And once the packed library is compiled it is read only, the internal structure is basically a sort of ZIP archive but the semantics are that of a compiled DLL. You can of course delete the DLL from the packed library directory and make sure it is loaded by other means before you attempt to load the packed library. That should in principle work but is of course a complication of the loading of such an app.

Rolf Kalbermatter
My Blog
Message 24 of 32
(973 Views)

@rolfk wrote:

wiebe@CARYA wrote:

From LabVIEW though, when building a packed library, there could be an option to specify if the dll should be copied with the library or not.

 

If the packed library uses a project central dll (one that is always available in the project anyway, or used in several libraries) is a different situation than a (more typical) library wrapping around a dll. The first use case isn't really supported right now, and an optional copy of the dll would fix that.


There is a fundamental problem with this. The compiled VIs in the packed library need to know the location of the assembly if it is not located in the GAC or the process root directory. And once the packed library is compiled it is read only, the internal structure is basically a sort of ZIP archive but the semantics are that of a compiled DLL. You can of course delete the DLL from the packed library directory and make sure it is loaded by other means before you attempt to load the packed library. That should in principle work but is of course a complication of the loading of such an app.


The only alternative we have now is to get a renamed copy of the dll for each packed library.

0 Kudos
Message 25 of 32
(967 Views)

wiebe@CARYA wrote:

@jamesbond0007 wrote:

I also tried doing something mentioned here but it does not seem to work.


That does seem useful for the problem. If we can get it to work.

 

Did you get stuck, or did it just not work?


It either didn't work or I didn't implement it correctly.

0 Kudos
Message 26 of 32
(954 Views)

@cbutcher wrote:

wiebe@CARYA wrote:

@cbutcher wrote:

I tried out a post build VI but discovered that it wasn't needed (and didn't do what I wanted anyway).

 

I meant to delete it from the build spec but perhaps I forgot when I uploaded. In any case, as you pointed out, you don't want to use it 🙂


Thanks for all the hard work!

 

Although it seems to solve the problem, the solution does have a side effect (a copy of the dll for each packed library). This 'side effect' might be acceptable for OP, it's hardly ideal.

 

Is it fair to say that this still is a problem in LabVIEW?

 

Should this be an idea on the idea exchange?


Ah. Found the quote button again 🙂

Anyway...

as to that side effect, I'd imagined that the OP would install the DLLs into some shared folder (e.g. C:\MyAwesomeDLLs\") and that each PPL would just overwrite the previously installed version with the newly installed version.

Wouldn't that work/be what was needed?

 

Potentially it would make a mess of versioning... but that could probably be worked around using versioned directories and symbolic links/junction points, if needed (as is common for some libraries on Linux systems).


No, the build process would not allow me to overwrite the DLL.

 

For example, if I reference the DLL in C:\CommonDLLs in my development code (inside a *.lvproj/ *.lvlib), and try to create source file settings to copy that same file into the same common folder (C:\CommonDLLs in this case), there will be an error saying that I cannot set the same destination folder as the source's or something in that line. Is that what you meant by overwriting the previously installed version with the newly installed version?

0 Kudos
Message 27 of 32
(953 Views)

Ah, no - you can't overwrite the source library when building.

Wiebe mentioned that installing the library to a specific location would create a new copy for each PPL - I just meant you could have them all reference the same installed version of the DLL.

They need to have a separate source though...

 

As Rolfk already pointed out (I think twice), this isn't the way that .NET DLLs are typically loaded. I'd guess that the PPL, on compilation, includes the additional information (e.g. path) necessary to load the assembly.

I don't know whether or not this really constitutes DLL hell though. If I tried using it for a real application, maybe I'd see the shortcomings.

It seems like it fulfills your needs, but I'd generally suggest listening to whatever Rolfk says on the topic of C, C++, (insert other text-based languages here), DLLs, system libraries, load paths etc... so maybe there are problems I didn't see.


GCentral
0 Kudos
Message 28 of 32
(948 Views)

@cbutcher wrote:

Ah, no - you can't overwrite the source library when building.

Wiebe mentioned that installing the library to a specific location would create a new copy for each PPL - I just meant you could have them all reference the same installed version of the DLL.

They need to have a separate source though...

 

As Rolfk already pointed out (I think twice), this isn't the way that .NET DLLs are typically loaded. I'd guess that the PPL, on compilation, includes the additional information (e.g. path) necessary to load the assembly.

I don't know whether or not this really constitutes DLL hell though. If I tried using it for a real application, maybe I'd see the shortcomings.

It seems like it fulfills your needs, but I'd generally suggest listening to whatever Rolfk says on the topic of C, C++, (insert other text-based languages here), DLLs, system libraries, load paths etc... so maybe there are problems I didn't see.


I'm not disagreeing with Rolfk here.

 

But the problem is that a packed library conflicts because it includes a copy of the used dll.

 

Your solution is to rename the dll so it doesn't conflict. This could get ugly when you have 10 libs that use the same dll. If the assembly has global resources (not sure if that's possible in .NET), these resources might not be shared between all the copies. Or maybe they are, but I'd prefer not to have 10 copies...

 

Another solution would be to (add a feature to) tell the builder not to copy the dll when building a packed library.

 

This has little to do with how, when and from where windows loads an assembly. It is about why and when LabVIEW copies the dll.

0 Kudos
Message 29 of 32
(929 Views)

wiebe@CARYA wrote:

Your solution is to rename the dll so it doesn't conflict. This could get ugly when you have 10 libs that use the same dll. If the assembly has global resources (not sure if that's possible in .NET), these resources might not be shared between all the copies. Or maybe they are, but I'd prefer not to have 10 copies...

That is more than theoretical, but basically a badly constructed example to proof that something is wrong with LabVIEW 😁.

I would strongly suggest that an assembly that needs to be accessed by two or more different packed libraries, let alone 10, is a VERY strong candidate for an assembly that absolutely needs to be located in the GAC. Either the assembly is specialistic and you should be able to wrap it with a single VI library or it is universal and then it should be in the GAC. A situation where you have a specialistic assembly that needs to be interfaced from many different places in your code without a single VI library wrapping its functions is an absolute disaster waiting to happen whenever you need to modify that assembly somewhere.

 

Another solution would be to (add a feature to) tell the builder not to copy the dll when building a packed library.

That's a potential improvement to the current situation except there is then a serious problem with Windows letting it locate that assembly. Unless it is in the GAC or the process root directory Windows won't find it for you and the packed library (or executable, compiled dll) won't have any extra information to try to locate it either. You could circumvent that with a manifest file located next to the process startup stub (exe file) but not with a manifest file next to the dll or packed library since that is not what Windows will look for and expecting LabVIEW to do manifest parsing and second guessing Windows search strategies is unrealistic.

 

This has little to do with how, when and from where windows loads an assembly. It is about why and when LabVIEW copies the dll.


They are very much related. You have two cases:

1) The assembly is in the GAC. LabVIEW recognizes that and does NOT copy the assembly DLL. It does only store the assembly name and version and not the path since that can be theoretically different on different platforms. When loading the packed library, LabVIEW dll or compiled exe, LabVIEW requests from Windows to load the assembly with name and version only and Windows will satisfy that by finding the assembly (either in the GAC or optionally in the process root directory) and otherwise fail after which LabVIEW has no other recourse than to open the compiled product with broken arrow.

2) The assembly is not in the GAC. LabVIEW copies the assembly into the same directory as the packed library, compiled DLL or built executable (optionally the data directory) and stores the relative path in the compiled code, or if you specify an absolute path to store the assembly to it will store that absolute path in the compiled code. LabVIEW will then attempt to load the assembly from that location and if that fails it may try to load the assembly with name only which would let Windows search it in the GAC or the process root directory and that's it. After that all standard .Net search locations have been exhausted and the broken arrow is the only remaining recourse.

 

 

Rolf Kalbermatter
My Blog
Message 30 of 32
(922 Views)