NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Capturing Engine pointer from external App

Solved!
Go to solution

Hello,

 

I need to make some program to change a Global from a running sequence. Simplifying it, i need to change a boolean Global with an external app (in c#). If anybody has done something similar, i would want to know how.

 

Until now, ive tried to save the object pointer in the configuration file, through TestStand and through another c# app , but it was no good 'cause it save it as a COM object. I am trying now to use Remoting Services to launch a service(with current Engine) with TestStand so my app could communicate with the Engine through Remoting.

 

I've tried my server-client without TestStand and works fine, but i cannot make them work if i launch server through TestStand.

 

I dont know more ways to Capture the Engine pointer... Any idea?

 

Daniel

0 Kudos
Message 1 of 6
(4,492 Views)
Solution
Accepted by topic author DanielPadillaCarrasco

Probably the easiest thing to do would be to use a TestStand queue or notification to pass the data between processes. Using the step type, if you start the name of a queue with a '*' character then the queue will be global to the entire machine. In order to programmatically access the queue from your external application, create an instance of the teststand engine and call GetSyncManager() on it with the name of your queue (i.e. it should begin with a '*' character). Then use the TestStand synchronization manager API with the returned synch manager to get the existing queue and access it. Notifications can also pass data and could be used the same way. You could store the global variable itself by reference in the queue and get it from the external application using Dequeue into a TestStand Object Reference variable (pass false for the removeelement parameter so that it stays in the queue for the life of the queue). See the teststand help file for the synch manager and queue API info. You can create a TestStand object reference variable to store the dequeued item using Engine.NewPropertyObject(). Then once it's in there simply call GetValueInterface and access the returned value as a PropertyObject itself.

 

Hope this helps,

-Doug

Message 2 of 6
(4,489 Views)
Hello dug9000, Thanks for the reply. I'm trying to make as you say but 1st i cant use an ' * ' before my queue name in TS 4.1.1. Maybe it's only a wrong configuration, but i dont find where to fix it. It will be the same if i use a Station Global Obj Ref instead of a queue? I tried the Station Global solution, but i couldn't use it. Could you link me an example of how to do this little code? i'm not very used to TS .NET API and it will be great a link or an explanation. Thanks, Daniel
0 Kudos
Message 3 of 6
(4,466 Views)

Hello dug9000,

 

i have tried some more, i understood to put ' * ' to the var name not to the name of the queue. I have investigated something and i have captured, finally the engine var from my c# APP. Thanks so much!!

 

I paste the solution in case anybody have the same problem:

-First on TS Sequence:

          Create a Queue with the name string: "*GlobalQueue"

          Enqueue RunState.Engine

 

-On C# app:

Add COM "NI TestStand Synchronization X.X.X" reference to the project and include its namespace.

then use:


            Engine engine = new Engine();
            SyncManager syncMgr = engine.GetSyncManager("*GlobalQueue") as SyncManager;
            Queue q = syncMgr.GetQueue("*GlobalQueue");

            WaitResult wr;
               
            PropertyObject po = engine.NewPropertyObject(PropertyValueTypes.PropValType_Reference, false, "Engine", 0);
            q.Dequeue(false, true, po, 2, null, false, out wr);
            Engine Runningengine = po.GetValInterface("", 0) as Engine;

 

Now I have the Running engine i'll try to change some globals ^^. Thanks

0 Kudos
Message 4 of 6
(4,461 Views)

Glad you were able to figure out what I meant. Looks pretty good for the most part, but there are a few minor issues with the code you posted that you might want to address as follows:

 

1) You should pass an empty string "" for the type name parameter of NewPropertyObject instead of "Engine". That parameter is for custom data type type names. It's probably getting ignored for non-container valuetypes, but you should really be passing an empty string.

2) You might want to use a longer timeout (or an infinite timeout) or check the waitresult to be sure that the timeout didn't occur.

3) You might actually want to pass true to remove element if you don't want to leave it in the queue and are doing the dequeue only once.

 

Anyway, glad you were able to get things working.

-Doug

0 Kudos
Message 5 of 6
(4,448 Views)

Hi,

I try to use this sample to share data (.net object) between TS and external .net process :

 

m_Engine = new Engine();
m_SyncObj = (SyncManager)m_Engine.GetSyncManager("*GlobalExec");

m_Queue = m_SyncObj.GetQueue("*SeteGlobalExec");

PropertyObject Obj = m_Engine.NewPropertyObject(PropertyValueTypes.PropValType_Reference, false, "", 0);

m_Queue.Dequeue(true, true, Obj, 1.0, null, false, out waitResult);

myObject = Obj.GetValInterface("", 0);

 

"myObject" is a COM Object. How can I convert this COM object into final Object to access to properties ans methods?

 

Thanks for your help

maxime

 

0 Kudos
Message 6 of 6
(3,191 Views)