NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Calling WPF from TestStand

Hello,

 

I was wondering if it is possible to develop WPF GUI's that can be called by TestStand.  Ultimately, I would like to create a WPF DLL which can be called by TestStand and fed parameters back and forth.

 

At the moment I'm trying to just do a very simple WPF form (no parameters, just a message in a window), however, I am having trouble doing this.  I am able to create the DLL in Visual Studio 2010 but when I try to call it in TestStand, it does not seem to work.  I'm also not sure if I am using the correct Action Adapter.  I tried calling it as a .NET adapter but when I do I get the following error:

 

An exception occurred inside of the call to .NET member 'UserControl1':
System.InvalidOperationException: The calling thread must be STA, because many UI components require this.
   at System.Windows.Input.InputManager..ctor()
   at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
   at System.Windows.Input.KeyboardNavigation..ctor()
   at System.Windows.FrameworkElement.FrameworkServices..ctor()
   at System.Windows.FrameworkElement.EnsureFrameworkServices()
   at System.Windows.FrameworkElement..ctor()
   at System.Windows.Controls.Control..ctor()
   at WpfControlLibrary1.UserControl1..ctor() in c:\users\mcooblal\documents\visual studio 2010\Projects\WpfControlLibrary1\WpfControlLibrary1\UserControl1.xaml.cs:line 22

 

I can attach files if that helps, just let me know.  In the meantime, I'm going to keep looking for solutions.

 

Thanks!

 

Mukesh.

0 Kudos
Message 1 of 14
(6,879 Views)

The error says, "The calling thread must be STA, because many UI components require this".

 

STA is a COM/ActiveX threading model. By default, TestStand threads use MTA rather than STA. Using a sequence call step with its execution option set to "new thread" you can call a sequence using an STA (Single Threaded-Apartment) thread by checking the option for it on the advanced panel of the module settings. You will then likely want a "wait" step immediately after the sequence call to wait for the thread to complete before continuing.

 

Another alternative is to do the equivalent in your .NET code module (i.e. create a new STA thread internally in your .NET code and have that run your dialog, while the original thread waits for it to complete).

 

Hope this helps,

-Doug

Message 2 of 14
(6,862 Views)

This is not a reply with answer, but more of a call to NI to provide more examples using TestStand with WPF.  Even better... release some plans on how this will work with WinUI and .NET Core.  NI, your customers are waiting/listening.  Thanks

Message 3 of 14
(4,624 Views)

Hello,

 

Since I experienced the same concern, here's an example that worked for me in a quick test with TS2019 (my main window is declared in Win.xaml):

 

public static void TestStandLaunchWPF()
{
Thread t = new Thread(() =>
{
var w = new Win();
w.ShowDialog();
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}

 

Regards

Message 4 of 14
(4,403 Views)

Thanks @thumble.  This worked for me, as well.

0 Kudos
Message 5 of 14
(4,393 Views)

By any chance did you try to make the wpf modal?

 

It seems it does not work.

 

I tried inside the thread and outside. Calling from another library and from inside the library that contains the WPF.

 

I checked the example from NI and they use forms and seems to work just like in CVI and LabVIEW.

 

Any advice?

Juan Navarro
0 Kudos
Message 6 of 14
(4,323 Views)

Hello, what do you mean by "make the wpf modal" ?

 

0 Kudos
Message 7 of 14
(4,296 Views)

I mean make the WPF dialog modal to teststand. I make it work on forms but cant on WPF.

Juan Navarro
0 Kudos
Message 8 of 14
(4,282 Views)

OK, my sample blocks TestStand execution in the calling step, but to make the windows modal you may look at https://www.codeproject.com/tips/226984/make-a-wpf-dialog-window-as-application-modal.

HAGD

0 Kudos
Message 9 of 14
(4,274 Views)

Actually I mean using the teststand API.

 

I used your example with some success, but I also want to to it modal to teststand like this.

 

public static void ShowSerialDialogWPF(SequenceContext seqContext, out string serialNumber, out bool continueTesting)
{
Engine engine = seqContext.Engine;
bool shoudAbort = false;
int modalId = 0;
bool continueTest = false;
string currentSerial = "AllFail";


modalId = engine.NotifyStartOfModalDialogEx(seqContext, out shoudAbort);

System.Threading.Thread uiThread = new System.Threading.Thread(() =>
{
continueTest = UserInterface(out currentSerial);
});
uiThread.SetApartmentState(System.Threading.ApartmentState.STA);
uiThread.Start();
uiThread.Join();

continueTesting = continueTest;
serialNumber = currentSerial;

engine.NotifyEndOfModalDialog(modalId);

bool UserInterface(out string selectedSerialNumber)
{

SerialDialog userInterfaceDialog = new SerialDialog();
userInterfaceDialog.ShowDialog();
selectedSerialNumber = userInterfaceDialog.Serial;
return userInterfaceDialog.ContinueTesting;


}

}

 

As you can see I want to use 

 

modalId = engine.NotifyStartOfModalDialogEx(seqContext, out shoudAbort);

 

But with no success in WPF

 

I was successful in windows forms but not WPF.

 

Juan Navarro
0 Kudos
Message 10 of 14
(4,261 Views)