01-02-2021 07:46 AM
Hi,
I have been reading a number of posts and help articles on how to close a Custom UI automatically, but I am having real problems getting it to work as expected.
The Bottom line is I am trying to "simulate" what happens when I press the axAppExit button on the NI simple example but via the API, what is see is the axAppExit button always closes without the "incomplete executions popup" but my method always gets the popup.
I am using the UI_EndExecution message to "I thought" ensure everything has finished before I fire of my - this.axExecutionViewMgr.GetCommand(CommandKinds.CommandKind_Exit, 0).Execute(true);
Detailed description
----------------------------
UI in C#, I started with the NI Basic example.
Running a custom sequential model. On starting the UI it automatically load and start my single SequenceFile in "Test UUTs" entry point.
this.sequenceFile = this.axApplicationMgr.OpenSequenceFile(SystemFunctions.PathsGlobal["MainTestSeq"]);
if (this.autoStart) // Execute the loaded sequence file currently configured as index 0 for Test UUTs
axSequenceFileViewMgr.GetCommand(CommandKinds.CommandKind_ExecutionEntryPoints_Set, 0).Execute(true);
In the model I have added a new Callback that the SequenceFile overrides to check all the hardware is present and initialising correctly. If something goes wrong I display the information to the user and give them the choice of retrying or to Exit the Application. If they select to exit the application --
send a custom UI message
// UI code snippet
// Set Hardware Initialise Fail Flag to allow Exit of Application
case UIMessageCodes.UIMsg_UserMessageBase + 84:
{
hardwareInitFailTriggeredShutdown= true;
}
break;
Then in a Post Action - sequence file
On Condition True - Terminate execution.
Locals.ExitConditions._Exited_k__BackingField
The the UI wait for the EndExecution event to be sent by the TestStand engine and call the CommandKiind_Exit
// UI code snippet.
case UIMessageCodes.UIMsg_EndExecution:
// check if it is the Test UUTs execution that has triggered message
if (e.uiMsg.Execution.DisplayName.StartsWith("Test UUTs"))
{
if (alarmTriggeredShutdown || hardwareInitFailTriggeredShutdown)
{
// shut down software
this.axExecutionViewMgr.GetCommand(CommandKinds.CommandKind_Exit, 0).Execute(true);
}
}
I would be grateful for any suggestions
regards
Danny
Solved! Go to Solution.
01-06-2021 03:54 AM
Hi Danny,
It sounds like we have most of the functionality that we want other than closing the popup.
I had a look through some documentation and it seems there isn't immediately a way to automatically select "Yes" on the prompt. It seems that calling
Runstate.Engine.GetInternalOption(InternalOption_ApplicationMgr).GetCommand(CommandKind_Exit, 0).Execute(false) will receive a pop-up if you're in an execution thread.
Are you able to call this from a non-execution thread instead? I believe this would skip the popup.
Cheers,
Nick
01-06-2021 11:24 AM
I shall see if I can try that tomorrow cheers Nick
01-08-2021 04:54 AM
So I have finally managed to fix my problem and I thought Id post my solution here in case anybody else has a similar issue.
Nick, you pointed me down the right line, thank you 👍
The original code was the correct calls BUT the CommandKind_Exit needs to be outside of the EndExecution handling case.
I remember now reading that the UI messages are basically blocking, so I was trying to Exit the engine which it was still running and waiting for EndExecution callback to return. The phrase "having my cake and eating it" comes to mind 🙄
So I created a very small C# async method that polled a new shutdownCommand Boolean and called CommandKind_Exit when true and the only thing I did in my EndExecution case was set that flag true I was wanted to Exit, thus it could return straight away.
Obviously care need to be taken that the async method is also exited correctly for any type of shutdown event.
case UIMessageCodes.UIMsg_EndExecution:
// check if it is the Test UUTs execution that has triggered message
if (e.uiMsg.Execution.DisplayName.StartsWith("Test UUTs"))
{
if (alarmTriggeredShutdown || hardwareInitFailTriggeredShutdown)
{
// shut down software
shutdownCommand = true;
}
}
private async void checkForShutDown()
{
while (continueShutdonwCheck)
{
task.delay(200);
if (shutdownCommand)
{
this.axExecutionViewMgr.GetCommand(CommandKinds.CommandKind_Exit, 0).Execute(true);
continueShutdonwCheck = false;
}
}
}