LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Massive .NET versioning issue in LV 8.6?

Hi all,

while I was posting some replies on a .NET event handling problem, I set up an assembly version related test scenario and ran into the following issue:

1. I created a .NET DLL with a simple method VersionString(string Name) that returns the assembly version together with the Name parameter. The C# code behind this is:
return "Hello " + Name + ", the version is: " + Assembly.GetExecutingAssembly().GetName().Version.ToString();

2. The assembly is signed = given a strong name and installed to the GAC (Global Assembly Cache) automatically after compilation.

3. I compiled 2 versions of the DLL with AssemblyVersion attribute set to "1.0.*" and "1.1.*"

4. Looking at the GAC in Windows Explorer, you find both versions there. [see attached screenshot 1]

5. The LabVIEW 8.6 constructor node lets you correctly select the assemblies directly from GAC, without the need to brwose for a path etc.. [2]

6. I placed 2 constructor nodes in a diagram, one for each available assembly version, and called the same VersionString method on both object instances. [3]

7. One should expect to get different results, like I yielded with another test application in C#, but the actual result in LabVIEW is: both .NET method calls return the same string from the 1.0.* version assembly! [4]

8. What fits to this misbehaviour is, the tooltip in the VI diagram shows an incorrect strong name on both constructor nodes with a version info of "0.0.0.0". [5]


Assumption: LabVIEW does not retrieve/store valid version info on strong named assemblies.
Any comments on that?

Cheers,
Hans
0 Kudos
Message 1 of 17
(7,035 Views)

Hi Hans,

 

can you attach your .NET Project and the Labview VI?

So we can try to reproduce this issue here.

 

 

Regards
DianaS
0 Kudos
Message 2 of 17
(6,974 Views)

can you attach your .NET Project and the Labview VI?


Sure, I've zipped and attached the entire Visual Studio 2008 Solution along with the caller VI.

Some brief comments on this:

 

1. Along with Visual Studio resp. the .NET SDK you have gacutil.exe available on your machine, which is used to copy the compiled assembly to GAC with the post-build event. Another option would be to drag & drop LabVIEWversioning.dll into the C:\Windows\assmbly folder in Windows Explorer by hand.

 

2. The LabVIEWversioning 2009-02-05.reg file inside the _ForumPost folder creates 2 registry keys to have the named DLL versions available in the references dialog of Visual Studio. I used this to have the specific GAC DLLs in the references dialog for my C# VersionConsumer project. This *.reg won't work after a new compilation, because of the automatic release counting of the assembly, and needs to be adapted if you want to do so, too!

 

3. The ZIP archive reveals that I'm a ReSharper user, a cool and almost inevitable Visual Studio Add-In. Should not have any effect to open the solution in VS without ReSharper.

 

Cheers,

Hans

Message Edited by HJPhilippi on 02-12-2009 11:53 AM
Message Edited by HJPhilippi on 02-12-2009 11:55 AM
0 Kudos
Message 3 of 17
(6,967 Views)

Hi Hans,

 

When you have two DLLs with the same name and the same functions then LabVIEW will only load one of those from the application memory space. This is similar to the concept of trying to place two subVIs with the same name on a block diagram. LabVIEW will only execute one of them, i.e., the one that was placed first. 

 

This forum throws a little more light on this matter:

 

http://forums.ni.com/ni/board/message?board.id=170&message.id=382423&requireLogin=False

 

You should somehow incorporate the versioning information in the DLL name itself!

Regards
DianaS
0 Kudos
Message 4 of 17
(6,915 Views)

Hi Diana,

 

I know that it's problematic or even impossible to load two VIs or two Win32 DLLs with the same name. But with .NET, it's a completely different story. The .NET assembly version and strong name principles address such kind of problems, indeed they are intended to operate "the same" DLL, in different versions, side by side - even within the same caller application.

To illustrate this, I've written a VI that creates late bound object instances by using the .NET Reflection namespace (see screenshot). It works well, 2 objects of the same type but different versions are created side by side, from a DLL with the same name! And this is how I would expect the intrinsic LabVIEW constructor node to operate - but it doesn't, it does not handle the classified type names including version info properly. LabVIEW simply takes the first matching DLL it finds, no matter what version you've selected in the constructor node dialog. And this is definitely a bug.

 

Getting back to the original problems that made me do all this investigations. People are having problems with their VIs when assembly versions change, like we had, too: .NET nodes are broken, event callbacks won't work anymore etc.. And I suspect it's related to those version issues.

 

Cheers,

Hans

Message 5 of 17
(6,898 Views)

Hi:

 

Was this issue ever resolved?  I'm having the same kind of issues with my .NET application calls...

 

Thanks!
-Jon

0 Kudos
Message 6 of 17
(6,565 Views)

jlschrad wrote:

 

Was this issue ever resolvedI'm having the same kind of issues with my .NET application calls...


Hi Jon,

 

I'm using a LabVIEW 2009 evaluation version (9.0f2) right now and the problem is the same, the .NET constructor node obviously misbehaves: If you have various versions of an assembly in GAC side by side, LV takes the first one it finds or assumes to fit, no matter what (different) version you've selected with "Select constructor..."

The only chance you have in this case is to avoid LV's constructor node and do a manual load of the desired assembly version using .NET intrinsic techniques, like I've demonstrated in my previous post. If you do a type cast of the resulting .NET object instance to the desired .NET class, you have the correct version running behind it.

 

Hopefully you didn't change the interface between the different versions (added/removed public members), since that would get you in a similar trouble. Although... maybe LV is able to differentiate the correct versions then? Will have to check this.

 

Cheers,

Hans

Message 7 of 17
(6,535 Views)

Hello,

 

For info, cross-posting other issue (with LV 2009 SP1) that might be related to same cause:

.NET constructor: error loading DLL in LabVIEW exe ...

 

Regards,

 

Vincent

 

0 Kudos
Message 8 of 17
(6,246 Views)

>To illustrate this, I've written a VI that creates late bound object instances by using the .NET Reflection namespace (see screenshot).

 

Hi Hans,

 

I can't seem to find the Assembly you used listed containing the .NET Reflection namespace when I drop a constructor onto my LV BD.  Did you build your own assembly with the .NET Reflection namespace in it, or should it already be in the GAC  ?

 

rgds

 

Peter
0 Kudos
Message 9 of 17
(6,177 Views)

Hi Peter,

 

the System.Reflection namespace resides (somewhat hidden to LabVIEW) inside the mscorlib.dll and the used Load() method is a static member of the Assembly type, that is: you don't place a constructor but an invoke node on the diagram directly, select the Assembly class and the desired method without creating an instance first:

 

mscorlib-system-reflection.png

 

Whenever you're looking for the location of a class/namespace, the MSDN is your friend:

http://msdn.microsoft.com/en-us/library/ky3942xh(VS.80).aspx

 

Does help?

 

Greetings,

Hans

0 Kudos
Message 10 of 17
(6,163 Views)