Jump to content

Issues calling .NET DLLs from LabVIEW


Recommended Posts

Hello,

My LV ver: 8.2

A vendor has given me some instrument drivers in the form of .NET DLLs (several DLLs). I've been able to sucessfully write wrappers (.VIs) around them, and all seem to be working fine.

The issue I'm running into is the following: very randomly, an exception is thrown by the DLLs (I still don't know why that is). The LabVIEW error describes more or less the following: "Cannot find abc.dll at C:\Program Files\etc etc" . If I manually copy the DLL to the expected path all works fine once again. However, the error will show up again after a while, and this time, it wants the abc.dll at some other location. Again, if I manually copy the DLL to the expected path all works ok.

I've looked into "registering" the .NET DLLs up front, but so far have not been able to find a way to do this.

LAVA gurus, any pointers will be much appreciated.

Link to comment

QUOTE (nitulandia @ Jan 28 2009, 10:31 AM)

Hello,

My LV ver: 8.2

A vendor has given me some instrument drivers in the form of .NET DLLs (several DLLs). I've been able to sucessfully write wrappers (.VIs) around them, and all seem to be working fine.

The issue I'm running into is the following: very randomly, an exception is thrown by the DLLs (I still don't know why that is). The LabVIEW error describes more or less the following: "Cannot find abc.dll at C:\Program Files\etc etc" . If I manually copy the DLL to the expected path all works fine once again. However, the error will show up again after a while, and this time, it wants the abc.dll at some other location. Again, if I manually copy the DLL to the expected path all works ok.

I've looked into "registering" the .NET DLLs up front, but so far have not been able to find a way to do this.

LAVA gurus, any pointers will be much appreciated.

A couple of questions - do these errors happen while the VI's are executing? Or do they happen after a VI that calls a .NET DLL is closed and then re-opened? I'm guessing the latter but more info would help me understand

Thanks,

Mark

Link to comment

Hello Mark,

The errors are being generated while the VI is running. I've attached a .bmp which shows for example, where the exception is coming from, and the error msg described previously. Note that it IS NOT always the same method that throws the exception, however, it seems that it is always complaining about the same DLL though. In other words, even though I have 7-8 dlls, LabVIEW wants to see the same abc.dll in different locations.

Link to comment

QUOTE (nitulandia @ Jan 28 2009, 01:59 PM)

Hello Mark,

The errors are being generated while the VI is running. I've attached a .bmp which shows for example, where the exception is coming from, and the error msg described previously. Note that it IS NOT always the same method that throws the exception, however, it seems that it is always complaining about the same DLL though. In other words, even though I have 7-8 dlls, LabVIEW wants to see the same abc.dll in different locations.

Thanks for the info - this probably isn't what I first suspected, so I'll ask more questions. You describe the error as a LabVIEW error and as an exception - is it indeed an exception thrown by the .NET assembly? Or is it an error generated by the LabVIEW call? Can you attach the error message and error code?

Thanks,

Mark

Link to comment

QUOTE (mesmith @ Jan 28 2009, 03:24 PM)

Thanks for the info - this probably isn't what I first suspected, so I'll ask more questions. You describe the error as a LabVIEW error and as an exception - is it indeed an exception thrown by the .NET assembly? Or is it an error generated by the LabVIEW call? Can you attach the error message and error code?

Thanks,

Mark

Hi Mark,

I'll post the error msg once I get it to occurr again. I'm not able to replicate the error pattern from run to run. The only "pattern-like" I've found is that if I shut my machine down-and-up, and then try to run my VIs, this is when it may (or may not) happen.

Some more details:

-The .NET DLLs are in the same folder location as my VIs.

-I've also added the DLLs and VIs to My LV prj

Link to comment

QUOTE (nitulandia @ Jan 28 2009, 04:14 PM)

Hi Mark,

I'll post the error msg once I get it to occurr again. I'm not able to replicate the error pattern from run to run. The only "pattern-like" I've found is that if I shut my machine down-and-up, and then try to run my VIs, this is when it may (or may not) happen.

Some more details:

-The .NET DLLs are in the same folder location as my VIs.

-I've also added the DLLs and VIs to My LV prj

Hello Mark,

This is the error msg:

"Error accessing property EieParallelTest.TestManager.Api.Interface.IEnvironment.Controllers of ObjectId handle: 0x5A5115C for obj 0x2B8BB1[EieParallelTest.TestManager.Environment] in domain [LabVIEW Domain for Run] and thread 7464, (System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.

Inner Exception: System.IO.FileNotFoundException: Could not load file or assembly 'file:///C:\Documents and Settings\user123\ABC.dll' or one of its dependencies. The system cannot find the file specified.

) in PROOF OF CONCEPT2.vi"

The error code returned is 1172.

If I manually put the ABC.dll in the path, my VI will work.

Link to comment

QUOTE (nitulandia @ Jan 28 2009, 04:55 PM)

OK - so if you put the DLL in the requested path, it works the next time you call the VI - but will it fail again later looking for the same DLL but now in a different path? That's what I think I read. And that is really pretty strange - sounds like the .NET assembly (DLL) may be buggy. Or, does it just take it a while to fail again? Since you said the problem is random, maybe it just works for a while because it doesn't try to execute that method? That is possible because a method invoked by reflection won't cause any problem until it is actually called at runtime - it's not like a DLL that loads when the calling application loads so if it doesn't get called the app could run for days if that particular method doesn't get called.

Anyway, there's nothing your LabVIEW code is doing to cause this - it's all happening in the .NET assembly so it may be up to the vendor to fix it. But here's a link to how .NET resolves paths to private assemblies

http://www.ondotnet.com/pub/a/dotnet/2003/...dingpolicy.html

The easiest way to deploy a .NET DLL is to include it in the same directory as the exe since that's always the first place .NET looks for it. So, if they aren't already there, try putting all the DLL's in the same directory. That should force the calling DLL to at least look for any dependencies there.

Mark

Link to comment

QUOTE (mesmith @ Jan 28 2009, 09:47 PM)

OK - so if you put the DLL in the requested path, it works the next time you call the VI - but will it fail again later looking for the same DLL but now in a different path? That's what I think I read. And that is really pretty strange - sounds like the .NET assembly (DLL) may be buggy. Or, does it just take it a while to fail again? Since you said the problem is random, maybe it just works for a while because it doesn't try to execute that method? That is possible because a method invoked by reflection won't cause any problem until it is actually called at runtime - it's not like a DLL that loads when the calling application loads so if it doesn't get called the app could run for days if that particular method doesn't get called.

Anyway, there's nothing your LabVIEW code is doing to cause this - it's all happening in the .NET assembly so it may be up to the vendor to fix it. But here's a link to how .NET resolves paths to private assemblies

http://www.ondotnet.com/pub/a/dotnet/2003/...dingpolicy.html

The easiest way to deploy a .NET DLL is to include it in the same directory as the exe since that's always the first place .NET looks for it. So, if they aren't already there, try putting all the DLL's in the same directory. That should force the calling DLL to at least look for any dependencies there.

Mark

Hi,

First, thank you for the comments.

In regards to your comment, yes, that is the observed behavior. "OK - so if you put the DLL in the requested path, it works the next time you call the VI - but will it fail again later looking for the same DLL but now in a different path? That's what I think I read".

It is very likely that this will fail again if I shut down-and-up my machine, however, I'm not able to reproduce this all the time. The only way I can get it to fail every time is if I completely remove the .dll from the last expected path.

And yes, I have all the vendor's dlls in the same location where my VIs are. And, all of these have also been added to my LV project.

BTW, my vendor is aware of the issue... and of course, the "finger pointing battle" has already begun. They claim that the issue here is LabVIEW :-) I'm planning on posting the solution to this issue once the root cause is found. For now I need to educate myself a little more on .NET assemblies, thanks for the link.

Cheers,

Eddie

Link to comment

QUOTE (nitulandia @ Jan 29 2009, 08:25 AM)

Hi,

First, thank you for the comments.

In regards to your comment, yes, that is the observed behavior. "OK - so if you put the DLL in the requested path, it works the next time you call the VI - but will it fail again later looking for the same DLL but now in a different path? That's what I think I read".

It is very likely that this will fail again if I shut down-and-up my machine, however, I'm not able to reproduce this all the time. The only way I can get it to fail every time is if I completely remove the .dll from the last expected path.

And yes, I have all the vendor's dlls in the same location where my VIs are. And, all of these have also been added to my LV project.

BTW, my vendor is aware of the issue... and of course, the "finger pointing battle" has already begun. They claim that the issue here is LabVIEW :-) I'm planning on posting the solution to this issue once the root cause is found. For now I need to educate myself a little more on .NET assemblies, thanks for the link.

Cheers,

Eddie

It's a long shot, but I found this instruction in the LabVIEW 8.6 help

"If you reference a .NET object from a VI that does belong to a LabVIEW project, the CLR considers the project to be the running executable. The CLR therefore searches for private assemblies in the project directory"

So if all your DLL's aren't in the same directory (and at the same level - not in subdirectories) as your lvproj file, try putting them there. Seems I'm rapidly running out of ideas!

Mark

Link to comment

QUOTE (mesmith @ Jan 29 2009, 09:42 AM)

It's a long shot, but I found this instruction in the LabVIEW 8.6 help

"If you reference a .NET object from a VI that does belong to a LabVIEW project, the CLR considers the project to be the running executable. The CLR therefore searches for private assemblies in the project directory"

So if all your DLL's aren't in the same directory (and at the same level - not in subdirectories) as your lvproj file, try putting them there. Seems I'm rapidly running out of ideas!

Mark

The solution (at this point the solution is conceptual, not implemented/tested just yet).

The problem seems to be with one of the .NET assemblies provided by the vendor.

Under "normal circumstances", these .dlls are installed (obviously with an installer) as part of some application. Clearly, a path is created and these DLLs look for some files at runtime at the expected path.

In my case I don't have this application installed, I'm just trying to make use of the .dlls.

Once I get a new set of DLLs from my vendor I'll post the test results.

By the way, I think I may run into a problem (this appears to be a real LV issue) when the new version of the assembly is provided. I'll have to re-link all of my wrappers to the new DLL. I read this on some other LAVA thread.

LAVA is cool.

Link to comment

QUOTE (nitulandia @ Feb 2 2009, 04:02 PM)

The solution (at this point the solution is conceptual, not implemented/tested just yet).

The problem seems to be with one of the .NET assemblies provided by the vendor.

Under "normal circumstances", these .dlls are installed (obviously with an installer) as part of some application. Clearly, a path is created and these DLLs look for some files at runtime at the expected path.

In my case I don't have this application installed, I'm just trying to make use of the .dlls.

Once I get a new set of DLLs from my vendor I'll post the test results.

By the way, I think I may run into a problem (this appears to be a real LV issue) when the new version of the assembly is provided. I'll have to re-link all of my wrappers to the new DLL. I read this on some other LAVA thread.

I'm surprised that the directory where the project file is located should work but if it does that is some special dealing LabVIEW is doing to inform .Net of additional paths. The default and first search location of .Net for assemblies is however in the current executables directory. This is NOT where your VIs are. This is where the executable is located that created the current process. For the LabVIEW development system this would be the directory where your LabVIEW.exe is located. For a built app this is where your myapp.exe is located.

Try this out to see if it would help with the current .Net DLLs.

Your Installer may put the .Net DLLs in the Global Assembly Cache (GAC). This is the second location searched by .Net for any .Net DLL if the first fails. But in order to be able to install .Net DLLs into the GAC they need to be strongly named (meaning they have a fully defined version resource and all).

These two locations (the executable directory and the GAC) are the only locations .Net will normally look for required DLLs. LabVIEW may do some extra magic to tell .Net to consider the project directory too, but this is in fact something that MSDN does advise to not do :rolleyes: , because it is an extra possibility to open the gates to DLL hell again.

Rolf Kalbermatter

Link to comment

QUOTE (rolfk @ Feb 5 2009, 02:22 AM)

I'm surprised, the directory where the project file is located should work but if it does that is some special dealing LabVIEW is doing to inform .Net of additional paths. The default and first search location of .Net for assemblies is however in the current executables directory. This is NOT where your VIs are. This is where the executable is located that created the current process. For the LabVIEW development system this would be the directory where your LabVIEW.exe is located. For a built app this is where your myapp.exe is located.

Try this out to see if it would help with the current .Net DLLs.

Your Installer may put the .Net DLLs in the Global Assembly Cache (GAC). This is the second location searched by .Net for any .Net DLL if the first fails. But in order to be able to install .Net DLLs into the GAC they need to be strongly named (meaning they have a fully defined version resource and all).

These two locations (the executable directory and the GAC) are the only locations .Net will normally look for required DLLs. LabVIEW may do some extra magic to tell .Net to consider the project directory too, but this is in fact something that MSDN does advise to not do :rolleyes: , because it is an extra possibility to open the gates to DLL hell again.

Rolf Kalbermatter

Hi Rolf,

Thanks for sharing those .NET details.

I'm no longer seeing the issue where LabVIEW wants to see certain DLLs in random paths. My vendor has fixed this issue.

The change made: they've given me an installer (as opposed to a .zip folder with all of the .NET assemblies in there). What happens with the installer is that it registers/installs the .NET assemblies in the GAC folder (C:\WINDOWS\assembly). Before the installer, and with the previous versions of the .NET assemblies I'm not sure what was going on.

Now, this is interesting as well: every time I get an update from my vendor, I have to manually re-link the constructor in every single VI I have created (wrappers to .NET assembly). Based on my what I've read, this is the nature of .NET assemblies. I had read in some other thread (on the web somewhere) that this was a LabVIEW issue, however, based on my limited knowledge and understanding of .NET assemblies, it seems like this is not a bug. In short, .NET assemblies don't behave like "normal" dlls.

I'll post more details If I run into more weirdness.

Regardless, I want to thank you all for the comments.

Cheers,

Eddie

Link to comment

QUOTE (nitulandia @ Feb 11 2009, 03:14 PM)

Hi Rolf,

Thanks for sharing those .NET details.

I'm no longer seeing the issue where LabVIEW wants to see certain DLLs in random paths. My vendor has fixed this issue.

The change made: they've given me an installer (as opposed to a .zip folder with all of the .NET assemblies in there). What happens with the installer is that it registers/installs the .NET assemblies in the GAC folder (C:\WINDOWS\assembly). Before the installer, and with the previous versions of the .NET assemblies I'm not sure what was going on.

Now, this is interesting as well: every time I get an update from my vendor, I have to manually re-link the constructor in every single VI I have created (wrappers to .NET assembly). Based on my what I've read, this is the nature of .NET assemblies. I had read in some other thread (on the web somewhere) that this was a LabVIEW issue, however, based on my limited knowledge and understanding of .NET assemblies, it seems like this is not a bug. In short, .NET assemblies don't behave like "normal" dlls.

I'll post more details If I run into more weirdness.

Regardless, I want to thank you all for the comments.

Cheers,

Eddie

Indeed. It is part of the strong name of .Net DLLs too. In order to be able to install a new version of a .Net assembly in the GAC one has to use an increasing version number. However the constructor node is strictly connected to the strong name of the assembly if available. So if you install a new version replacing the older one you have to reconnect the constructor node. This is a pita but not easy to circumvent and if one would try to circumvent it one would cause other problems when more than one version of a .Net component are installed on the same machine.

I'm not aware of a good workaround for this. Placing a .Net DLL (and its dependencies) into the application directory could litigate the issue a bit at the cost of saddling you with the distribution of the .Net assemebly with your application.

Rolf Kalbermatter

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.