07-14-2016 04:55 PM
At my company we use the following system for organizing VIs on a PC (all of which are running LabVIEW 2015, Windows 7):
Application code --> C:\LabVIEW Code\AppName\...
Common company libraries not related to instruments --> <user.lib>\LibName\...
LVOOP root class that all instrument drivers inherit from --> <instr.lib>\CompanyNameInstruments\
LVOOP child class implementing wrapper VIs for a certain instrument type --> <instr.lib>\CompanyNameInstruments\InstrumentType\
LVOOP child class implementing a specific instrument that overrides wrapper VIs--> <instr.lib>\CompanyNameInstruments\InstrumentType\SpecificInstrumentName
Every directory in user.lib, instr.lib, and "C:\LabVIEW Code\" has its own SVN repository.
This has worked OK for quite a while, with ~ 8 different instrument types and 1-3 specific instruments each. Most used VISA interfaces. We recently needed to add some motion control using ThorLabs Kinesis .NET DLLs, so I created <instr.lib>\CompanyNameInstruments\MotionController\ThorlabsKinesis\ and put in a ThorLabsKinesis.lvproj, a ThorLabsKinesis.lvclass, and so on. I installed the Kinesis software and it installed 112 DLLs (plus 30 other files that appear to be required to use the DLLs since they have the same filenames exactly as some of the DLLS, but different extensions), all of which I copied to the folder and added to the class as per recommendation from their Kinesis LabVIEW guide.
I then did my thing, creating wrapper VIs, and got a few assorted controllers and motors in which I proved I could control using "ThorLabsTester.vi" that I added to the project and the class. This part all worked fine, so I was done with the driver VIs and it was time to work on the code for the first station that needed to use the driver.
Here's where the problem started: The station code I wrote kept giving error 1172 (the most generic .NET error code possible for LabVIEW) with a message stating it was throwing a System.IO.FileNotFoundException because it couldn't find a DLL.
Experimentation showed that the driver VIs would work fine only under the following conditions:
And the driver VIs would fail under the following conditions:
This led me to this knowledge base article about how LabVIEW finds .NET DLLs listing 3 methods for locating .NET DLLs.
I was hoping that the "Relative path" option would work, but 1) there's 112 DLLs that would have to be added, which seems ridiculous since I only call about 15 of them directly and 2) a lot of those DLLs don't have public methods for me to create a constructor/property/invoke node for to get them in the VI in any case. I can't find a way to force LabVIEW to be told "If a DLL gets loaded, here's a directory where it should look for its friends" or something to that effect.
The "Specified Subdirectories" include both the folder the project is in, and the folder where LabVIEW.exe is. The plan is to use this driver on the one station for now, but we have future plans to roll out about 5 other stations that use the same driver but for different applications, and it's hard to say how many more in the future. I really don't want to have the same DLLs copied to 3 different locations per PC that we'll have to ensure all receive updates at the same time, etc.
The "Global Assembly Cache (GAC)" option seems like it would be an idea solution if it was easy to do. However, the ThorLabs installer doesn't register the DLLs to the GAC when it installs. I've spent hours trying to figure out alternate ways to accomplish this. All solutions I find seem to be in the following categories:
Is there something simple I have missed here? Has anyone else had the same issues with .NET DLLs for instrument control before? Is my only real option to copy ~142 files to 2 or 3 locations on every PC instead of leaving them in one central source-controlled directory in the "right" place for an instrument driver?
Thanks...
07-14-2016 08:45 PM
07-15-2016 12:01 PM
@mikeporter wrote:
it is anybody's guess how long before Windows completely locks down installation directories.
Mike...
Do you have a source for this or is it just a "feeling" you get as Windows 10 starts rolling out, etc.?
(I'm still looking for a better solution to this issue, but thanks for the reply)
07-15-2016 01:22 PM
07-15-2016 03:49 PM
I've managed a slight improvement. Still not great.
I can get LabVIEW to work with the DLLs without opening a project file first (which was one of the things I really didn't want to have as a requirement, since operators will be running these stations and shouldn't be expected to deal with having a project file open in addition to the main application).
In order to get it working without the project file open, I need to:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="C:\Program Files (x86)\National Instruments\LabVIEW 2015\instr.lib\CompanyInstruments\MotionController\ThorlabsKinesis"/> </assemblyBinding> </runtime> </configuration>
So it's still not really where I want it to be but it's progress of sorts.
07-17-2016 08:12 PM
Is building a stand-alone executable an option? If so, I have been able to get it working if I do 2 things:
It does mean copying all those files, but at least the built app is insulated from version changes of the dll's. Then you just run the built app.
07-18-2016 04:56 PM
Building an EXE is an "eventual" option. We do that when we "freeze" a station's development, i.e. when we've tested it live for a long enough time that we no longer have any significant amount of bug reports or feature requests and barring changes in the product line itself the station code shouldn't need to be modified further.
I have verified what you say, though. If I just add every DLL in all of the drivers that are used to the build, it does work.
One thing I did discover during the whole process is that it seems that the DLLs that I mentioned don't have public methods for me to create a constructor/property/invoke node are not in fact .NET DLLs, and are older-style DLLs that the .NET DLLs call, so it seems likely that the .NET calls are just wrappers for their old code. They offer both ActiveX/COM and .NET control methods for their products, so it could be they share these DLLs.
It may be that we'll just have to copy these DLLs all over the place and just do our best to ensure the same versions are used on a station-by-station basis instead of having a shared directory for all projects in SVN.