NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

How do I pass arguments to a TestStand sequence from an operator interface written in LabWindows?

I intend to use TS_EngineNewExecution() which takes a VARIANT parameter for the arguments.

I have only found example code for C++ where a propertyObject containing the arguments is converted to a VARIANT using the constructor of the _variant_t class.

How do I accomplish this in LabWindows?
0 Kudos
Message 1 of 13
(4,838 Views)
Stefan,

Passing parameters to a sequence from a CVI Operator Interface is very similar to the C++ code you've seen. However there are subtle differences (as you already noted) when in comes to converting the PropertyObject to a Variant. Here is a function that contains the code you need to pass arguments to a sequence from CVI:

void ExecuteSequence(char *sequenceName, VBOOL useProcessModel)
{
ERRORINFO errorInfo;
int error = 0;
CAObjHandle modelSeqFile = 0;
CAObjHandle params = 0;
char *modelDesc = NULL;
LPDISPATCH dispPtr; // varible used to convert parameters from CAObjHandle to Variant


// get the model sequence file if needed
if(useProcessModel)
oleErrChk( TS_SeqFileGetModelSeqFile (gCurrentSequenceFile, &errorInfo,&mod
elDesc, &modelSeqFile));


// Create container that will hold two parameters. First parameter is a number, second is a string.
oleErrChk( TS_EngineNewPropertyObject (gEngine, &errorInfo, TS_PropValType_Container, VFALSE, "", 0,¶ms));
TS_PropertySetValNumber (params, &errorInfo, "Param1", 1, 45);
TS_PropertySetValString (params, &errorInfo, "Param2", 1, "This is a string");

// Converts CAObjHandle to Dispatch pointer
errChk(CA_GetDispatchFromObjHandle (params, &dispPtr));

// run the specified sequence in the currently loaded file
oleErrChk( TS_EngineNewExecution (gEngine, &errorInfo, gCurrentSequenceFile,sequenceName, modelSeqFile, VFALSE,
TS_ExecTypeMask_Normal,CA_VariantDispatch(dispPtr), CA_DEFAULT_VAL,
CA_DEFAULT_VAL, &gCurrentExecution));

Error:
if(modelSeqFile)
CA_DiscardObjHandle(modelSeqFile);
if(modelDesc)
CA_FreeMemory(modelDesc);
return;
}

Let me know if you have any questions,


Azucena
Message 2 of 13
(4,838 Views)
Is there an example to show how to populate the "seqArgs" parameter of the TS_EngineNewExecution call?
0 Kudos
Message 3 of 13
(4,619 Views)
Hi webprofile,

I'm not sure that I understand your question given the previous post. These lines show how to populate the arguments into the newly created property object:

TS_PropertySetValNumber (params, &errorInfo, "Param1", 1, 45);
TS_PropertySetValString (params, &errorInfo, "Param2", 1, "This is a string");


Regards,
0 Kudos
Message 4 of 13
(4,594 Views)

Hi James

Thanks for the reply.

I am trying to modify the OI code with CVI under:

C:\Program Files\National Instruments\TestStand 3.5\OperatorInterfaces\NI\TestStand 2.0.1 Operator Interfaces (Old)\Full-Featured\CVI

There is a CVI project called: testexec.prj. This has an engine.c file, and a function called:

TERetval Eng_BeginSeqExecution. Within this function, there is a TS_EngineNewExecution function call, and I am trying to pass parameters to the sequence using the arguments to the TS_EngineNewExecution call (in place of the CA_DEFAULT_VAL). How do I pass a parameter in place of this CA_DEFAULT_VAL?

The example shows passing the editArgs parameter, while the seqArgs and the interactiveArgs are default.

Thanks

 

0 Kudos
Message 5 of 13
(4,591 Views)
Hi James,
To add to the above post, I do the following in C#. My sample.seq file requires a string to be passed as a parameters to the file.

axApplicationMgr1.Start();

mEngine=axApplicationMgr1.GetEngine();

CurrentSequenceFile=axApplicationMgr1.OpenSequenceFile("Sample.seq");

NationalInstruments.TestStand.Interop.API.PropertyObject pobj=mEngine.NewPropertyObject(NationalInstruments.TestStand.Interop.API.PropertyValueTypes.PropValType_Container,false,"",0);

pobj.NewSubProperty("param1",NationalInstruments.TestStand.Interop.API.PropertyValueTypes.PropValType_String,false,"",0);

pobj.SetValString("param1",0,"This is a new message");

mEngine.NewExecution(CurrentSequenceFile,"MainSequence",null,false,0,pobj,null,null);

And it works fine. How do I do the same thing in CVI?

Thanks

0 Kudos
Message 6 of 13
(4,584 Views)
Hi webprofile,

I did not extensively test this code, but based on the previous posts, this is what the function might look like (I bolded the changes from what ships by default):

///////////////////////////////////////////////////////////////////////////////

TERetval Eng_BeginSeqExecution(tSeqFileRec *seqFileRec, // must NOT be NULL
                               tSeqRec *seqRec,            // must NOT be NULL
                               ListType checkedStepList,
                               TEBool breakAtFirstTest)
{
    HRESULT res = 0;
    ERRORINFO errorInfo;
    TEBool errorOccurred = FALSE;
    CAObjHandle newExeH = 0;
    VARIANT editArgsVar;
    CAObjHandle editArgsH = 0;
   
    CAObjHandle params = 0;
    LPDISPATCH dispPtr; // varible used to convert parameters from CAObjHandle to Variant

    // Create container that will hold two parameters. First parameter is a number, second is a string.
    oleErrChkReportErrInfo(TS_EngineNewPropertyObject (sTEEngineObj, &errorInfo, TS_PropValType_Container, VFALSE, "", 0,&params));
    TS_PropertySetValNumber (params, &errorInfo, "Param1", 1, 45);
    TS_PropertySetValString (params, &errorInfo, "Param2", 1, "This is a string");
   
    // Converts CAObjHandle to Dispatch pointer
    TERetChk(CA_GetDispatchFromObjHandle (params, &dispPtr));

   
    TERetChk(CreateEditArgsObj(0, seqFileRec->seqFileH, seqRec->seqH, checkedStepList, &editArgsH));
    if (editArgsH) {
        LPDISPATCH editArgsDispatch = NULL;

        CA_GetDispatchFromObjHandle (editArgsH, &editArgsDispatch);
        editArgsVar = CA_VariantDispatch(editArgsDispatch);
    } else
        editArgsVar = CA_DEFAULT_VAL;
   
   
    oleErrChkReportErrInfo(TS_EngineNewExecution (sTEEngineObj, &errorInfo,
                                                  seqFileRec->seqFileH,
                                                  seqRec->seqName, 0,
                                                  TEBool2VBOOL(breakAtFirstTest),
                                                  TS_ExecTypeMask_Normal,
                                                  CA_VariantDispatch(dispPtr),
                                                  editArgsVar,
                                                  CA_DEFAULT_VAL, &newExeH));
    /* we'll get this again later on the StartOfExecution event
     * so free this reference to it */
    CA_DiscardObjHandle(newExeH);

Error:

    if (editArgsH)
        CA_DiscardObjHandle(editArgsH);

    return !(errorOccurred || res < 0); /* return TRUE if no errors occurred */
}

0 Kudos
Message 7 of 13
(4,572 Views)

Hi James,

Thanks for the reply.

I got it working with C#, but am not able to do it with CVI. Apparently, a property will not do it, I need to create a subproperty.

This is not the entire code, just a snippet.

Also, I get some warning that the handles to some of the variables I created (the seqArgsVar) have not been released. I guess in CVI, the CA_DiscardObjHandle discards the handles to the objects created. What is the equivalent in C#?

Thanks

try

{

axApplicationMgr1.Start();

mEngine=axApplicationMgr1.GetEngine();

CurrentSequenceFile=axApplicationMgr1.OpenSequenceFile("Sample.seq");

NationalInstruments.TestStand.Interop.API.PropertyObject pobj=mEngine.NewPropertyObject(NationalInstruments.TestStand.Interop.API.PropertyValueTypes.PropValType_Container,

false,"",0);

pobj.NewSubProperty("param1",NationalInstruments.TestStand.Interop.API.PropertyValueTypes.PropValType_String,

false,"",0);

pobj.SetValString("param1",0,"This is a new message");

mEngine.NewExecution(CurrentSequenceFile,"MainSequence",

null,false,0,pobj,null,null);

}

catch(Exception e)

{

MessageBox.Show(e.Message,"TestStand Error");

}

finally

{

mEngine.ReleaseSequenceFile(CurrentSequenceFile);

axApplicationMgr1.CloseSequenceFile(CurrentSequenceFile);

mEngine.ShutDown(

true);

axApplicationMgr1.Shutdown();

}

0 Kudos
Message 8 of 13
(4,567 Views)
Hi webprofile,

Are you trying to write your program in CVI, C#, or both?
If you are using CVI, does the code that I posted above not work?
If you are using C#, there is no equivalent to release the property object since C# is a managed language. I pasted your code into the simple C# OI at:
OperatorInterfaces\NI\Simple\CSharp
and I did not receive any warnings when I ran it.

Regards,
0 Kudos
Message 9 of 13
(4,540 Views)

Hi James

Thanks for the reply. I am writing with CVI.

Thanks

 

0 Kudos
Message 10 of 13
(4,537 Views)