nitulandia Posted January 29, 2009 Report Share Posted January 29, 2009 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. Quote Link to comment
Mark Smith Posted January 29, 2009 Report Share Posted January 29, 2009 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 Quote Link to comment
nitulandia Posted January 29, 2009 Author Report Share Posted January 29, 2009 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. Quote Link to comment
Mark Smith Posted January 29, 2009 Report Share Posted January 29, 2009 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 Quote Link to comment
nitulandia Posted January 29, 2009 Author Report Share Posted January 29, 2009 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 Quote Link to comment
nitulandia Posted January 29, 2009 Author Report Share Posted January 29, 2009 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. Quote Link to comment
Mark Smith Posted January 30, 2009 Report Share Posted January 30, 2009 QUOTE (nitulandia @ Jan 28 2009, 04:55 PM) 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. 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 Quote Link to comment
nitulandia Posted January 30, 2009 Author Report Share Posted January 30, 2009 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 Quote Link to comment
Mark Smith Posted January 30, 2009 Report Share Posted January 30, 2009 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 Quote Link to comment
nitulandia Posted February 3, 2009 Author Report Share Posted February 3, 2009 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. Quote Link to comment
Rolf Kalbermatter Posted February 6, 2009 Report Share Posted February 6, 2009 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 , because it is an extra possibility to open the gates to DLL hell again. Rolf Kalbermatter Quote Link to comment
nitulandia Posted February 12, 2009 Author Report Share Posted February 12, 2009 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 , 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 Quote Link to comment
Rolf Kalbermatter Posted February 12, 2009 Report Share Posted February 12, 2009 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 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.