NI TestStand

Showing results for 
Search instead for 
Did you mean: 

Can you programmatically add a .Net reference to TestStand StationGlobals?

I am modifying the C# TestStand Operator Interface and want to save a reference to an instantiated object to StationGlobals.  I am able to store .Net references returned by the .Net Adapter from a method in an assembly written in C# to an ActiveX Reference Station Global .  Is there a way to do this from within the assembly?  Using the SetValInterface() method creates a reference which TestStand reports as IUnknown and is unable to use as it does not see it as a .Net reference.   Using the SetValIDispatch() method causes a runtime error in the assembly.  Is there an equivalent SetValActiveXAutomationHandle() method?
0 Kudos
Message 1 of 13
Reading some other threads I've learned that LabView and TestStand are not able to share DotNet references.  Is this also a problem for a .Net Assembly and TestStand?
0 Kudos
Message 2 of 13

You cannot store the reference to StationGlobals and then get it back out since when it stores it there its stored as a .NET object inside of an ActiveX object and you don't have access to that ActiveX object in the OI. I'm still looking into whether or not what you're trying to do is possible and I'll let you know when I run some additional tests.

Message Edited by Jon M on 11-17-2006 04:41 PM

Message Edited by Jon M on 11-17-2006 04:41 PM

Test Engineer - CTA
0 Kudos
Message 3 of 13

After perfoming some tests based on what you are doing, it turns out that it is not possible to pass the reference.

Test Engineer - CTA
0 Kudos
Message 4 of 13

Has anything changed in TestStand since this posting?  I am storing a .Net reference in a Station Global variable of type "Reference" using the .Net adaptor.  If the DotNET adaptor is able to store a reference in a Station Global, it must be possible to also store a .Net reference from a custom operator interface using the TestStand API?  Or, is the adaptor using a private API that is not available to us mere mortals? 🙂

I am successful at storing a .Net reference from one sequence, so that other sequences can make method calls later on that same object later on in the lifecycle of my application.  That all works just fine....

The problem is that I am creating the .Net object from within a startup sequence, and it takes a fair amount of time for the sequence to load, execute, then instantiate the object.  If I could instantiate the object from within my custom operator interface at initial startup, then save the reference to the object in the Station Globals, my sequences that execute later can use the object.... Am I being perfectly obtuse?


0 Kudos
Message 5 of 13
The reason you can't use the objects created in your code module in your OI is the code module runs in a different AppDomain.  The OI application will run in the Default AppDomain. 

There are a couple of possible solutions, but I don't have the ability to test these right now. 

The first one I am not sure if it will work, but it might be worth a try.  You would have to run a .NET code module first to create the TestStand execution AppDomain.  In that code module use get the current AppDomain (it is a static property of the AppDomain class) and store it in a StationGlobal with SetValInterface.  You will also have to return some class reference from the code module and store it in a global reference.  If you don't do this, the TestStand AppDomain will be unloaded as soon as the code module you just ran is unloaded.  From the OI, try to get the reference to the AppDomain by calling GetValInterface on the variable.  If you are able to get the reference, you can create an instance of a class you create in the AppDomain to run whatever code you want to.  The class you create must inherit from MarshalByRefObject since it will be marshalled across AppDomain boundaries. 

The second option is to use .NET remoting to communicate across the AppDomain boundaries.  You would need to run a .NET code module that creates a .NET remoting server.  You would need to pass out a reference and store globally just like the last option so the TestStand execution AppDomain does not get unloaded.  This is probably the cleaner solution, but you will need to create the server and client code for the remoting.  There are many examples on the web on how to do this. 

While these solutions are not ideal, there is not a direct way of doing this currently.
0 Kudos
Message 6 of 13
Thanks for the reply. I am familiar with AppDomains, but I didn't know that the OI and sequences were running in different AppDomains.... I'll take a look at both of your ideas to see which would work better long-term!
0 Kudos
Message 7 of 13

Were you able to get to a resolution on this?

0 Kudos
Message 8 of 13

What exactly are you trying to do? Some things have changed over the years. For example, newer versions of TestStand and LabVIEW do support passing .NET objects between TestStand and LabVIEW (as long as they are serializable or derived from MarshalByRefObject).



0 Kudos
Message 9 of 13

I'm looking to run an initialization sequence execution which would initialize .NET objects and store them into station globals.  However, once that initialization sequence execution is done then the objects are gone.  I would be interested in storing them in my UI (though not the best design pattern) so at execution of the next flow I can populate those back without having to go through the initialization again.

0 Kudos
Message 10 of 13