08-04-2010 11:48 PM
Hi Hans,
Many thanks for your prompt and informative reply ! I was able to construct the BD as you did. This is a handy thing to know.
Would you mind if I PM'd you with some other .NET/LV questions ? You seem like quite knowledgable in both areas which is rare find. BTW I recently staretd a .NET/LV thread [1] to solve a problem and had nobody from the forums contributed (it was a thread btwn Adam Kemp and myself mirrored from Info-LV) This tells me there are not many seasoned .NET and LV programmers reading these forums.
[1] Re: Passing a Windows Form reference from C# .NET to LabVIEW
regards
08-05-2010 03:00 AM - edited 08-05-2010 03:01 AM
Hi Peter,
I think I've a greater knowledge in the .NET than in the LabVIEW area, although I know LV for over a decade now...
But sure, just ask me and we'll see if I can help!
Cheers,
Hans
11-08-2011 04:06 PM
So, it appears NI has never agreed this is a bug? I have run into this same problem in LV2011.
11-09-2011 02:04 AM
Well... As DianaS from NI answered above, I'm afraid they consider it as normal (can't load two different dlls with same name, end point) so it is no bug to them... It's a bit funny as NI introduced name caching for VIs (through .lvlib) so you actually can load different VIs with identical names now, but they don't recognize the same need for .NET assemblies.
Plus here the bug is relevant even with one single assembly loaded in memory in case of upgrade, at least according to my experience : Say you once loaded your assembly version 1 with a constructor in a VI. Then you update the assembly to version 2 with same dll name (but keep version 1 in GAC as it might be used by other software). Then you update ALL constructors of your VI to use version 2. Then you move your code to a machine where only version 2 is installed (always with same dll properly installed), and... LabVIEW complains it cannot run VI because dll cannot be found (it is here, but LabVIEW still tries to reference the version 1 assembly, although all constructors have been updated). You actually have to re-update constructors on a machine that ONLY has version 2 in GAC to succeed in the version update of your VI ! So it is not at all as trivial and logical as simple dll name as NI pretends, I'm afraid... They should really check this behavior more deeply...
As a side note, regarding LV 2011, at least now you have a new feature that might help (or might not depending how LabVIEW gets deeply confused with assemblies versioning, I haven't tried yet) : In View Menu, you have the ".NET Assemblies in Memory" browser that lets you see what is actually loaded in memory, with version number and dll name...
Have fun !
Vincent
11-09-2011 03:33 AM - edited 11-09-2011 03:35 AM
One never stops learning...
In the meantime, I further investigated the process, how LV loads assemblies and thereby produces so-called shadow copies of referenced .NET DLLs (see http://msdn.microsoft.com/en-us/library/ms404279.aspx). In my opinion, this is strongly related to the version problems, too. We still have issues with 3rd party .NET stuff and I asked NI, if you can change the default shadow copy behaviour of LV within its .NET application domain, but did not yet receive an answer from them...
Regarding the use of different versions on different machines. Have you ever tried version redirection via .NET configuration files? You "simply" have to create a plain text file named LabVIEW.exe.config next to the LabVIEW.exe, with a content similar to this:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="AssemblyNameWithoutExtension"
publicKeyToken="b03f5f7f11d50a3a"
culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0-1.5.0.0"
newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
You must replace the publicKeyToken b03f5f7f11d50a3a with yours or simply drop this attribute if your DLL is not signed. This will tell the consumer of the assembly that it's okay to use version 2.0, when 1.0 to 1.5 were referenced but cannot be found. More info on this topic once again in the MSDN: http://msdn.microsoft.com/en-us/library/eftw1fys.aspx
And (surprise, surprise) version redirection actually does work with LabVIEW, too. Wow. 🙂
Regards,
Hans
11-09-2011 05:06 AM
Unfortunately, I am actually trying to use two different versions at the same time. I am writing some code using SQL Server Compact Edition. V 3.5 and 4.0 both have .NET assemblies. I am trying to allow the user to use either version, but can't because of this problem.
I looked into loading the assemblies, as Hans showed in his example. That is OK, but I can't figure out how to use the Properties or Methods.
I may have to look into using the lower level DLLs to get this to work.
11-09-2011 05:27 AM
@Matthew Kelton wrote:
I looked into loading the assemblies, as Hans showed in his example. That is OK, but I can't figure out how to use the Properties or Methods.
Well, this in fact can become a bit tricky. A simple cast to the target class may do the job, but may also produce an exception if LabVIEW uses the shadow copy for instantiation and you referenced the target class of the LV diagram constant from another location... Pitfall after pitfall, this is the "joy" we have to deal with right now.
What surely will work is reflection, that is: calling methods and accessing properties by name. But that is [a] no fun to do and [b] pretty slow.
My approach to solve the problem you're stuck in was to write a wrapper class that handles DB accesses towards LabVIEW in a unique way. Whether SQL CE 3.5 or 4.0 is used is then handled inside the wrapper, not inside LabVIEW. And within the wrapper class, you may attempt to load version relevant assemblies into seperate application domains with switched off shadow caching to possibly circumvent the LV misbehaviours.
But this is pure speculation, just an idea i recently had and that is not yet tested.
Greetings,
Hans