In Legato you can make all sorts of different scripts that do many different tasks. A majority of these tasks come while you are working inside of GoFiler or another application, and when these are finished you simply return out of the script and the application continues on as normal. Sometimes, however, you are performing a task that must end with finality. In this case you can exit the program that is running your script. Today we are going to look at the ways in which you can accomplish this, how they are different, and times in which you would use each.
ExitApplication()
There is a function ExitApplication() that does what we are asking: exits the application after the current script ends.
int main() {
ExitApplication();
return ERROR_NONE;
}
If you were to execute the above code it would close GoFiler. There are, however, a few caveats to this that we need to keep in mind. The first caveat is that ExitApplication() assumes that you are running as a foreground application. If you are running as a console application this function will return ERROR_FUNCTION_NOT_SUPPORTED and will not exit the application. The second caveat is that the function posts a forcible quit message to the application. This means that if there are unsaved files open in the application those files will be lost as the application will not ask if the user wants to save them.
The other important piece of ExitApplication() that we need to keep in mind is the part of the description that says “after the current script ends.” This means once the script stops executing, even if an error is encountered, the application will exit. If you use this function call while a dialog is open, the application waits until the dialog is closed and the script ends before the exit message will be posted. Finally, if the script is a background process the close request is sent to the application frame right away, meaning that all future dialog and message boxes will be inhibited. This means that some thought needs to be used as to where and when to call the function. The best time to use the function call is when an error condition no longer matters in the script. Using this function call at the beginning of a script, then, is probably not the best idea as there are no guarantees that the script completes successfully before exiting the application.
RunMenuFunction()
The other way of exiting GoFiler through Legato is using RunMenuFunction():
int main() {
RunMenuFunction("FILE_EXIT");
return ERROR_NONE;
}
This will immediately post a message to Windows asking GoFiler to close the application. Due to timing issues, additional lines in the script may be executed and unexpected behavior may occur if this is not the last line in a script. The RunMenuFunction() is an attempt to “nicely” close the application because it is the equivalent of clicking on the “Exit/Quit” button in GoFiler. Any open files that are unsaved will have a prompt to the user asking them if they would like to save, which gives the user the option to cancel the exit operation. If the close operation is cancelled, script functions underneath the RunMenuFunction() call will definitely be executed. This means one may want to include some error checking or additional functions underneath that would only be called if the program did not exit.
So which operation is better? Well, as with most things in programming, it depends on what you are trying to accomplish. If your task is one which will absolutely need the program to close after it is done (such as if you are building your own Legato API) then ExitApplication() is your best option. If the task should have GoFiler close when it is done, but you want to be nice to a user or the program could presumably stay open, then you can use RunMenuFunction(). It all comes down to how forceful you want to be as a programmer.
One trick that you can use when you are initially developing a script that will close the application once it is done is to have a boolean “debugFlag” variable or definition that you check before running the ExitApplication() or RunMenuFunction() functions. This allows you to repeatedly run the script, get debug data, and run the script in the IDE without having to reopen the program between each run. When you are finished developing the script, just switch the define to the other value and you are all set to deploy your script.
Before we wrap up I want to talk quickly about how exiting the application works with the “RunScript” command line parameter:
C:\Users\joshua.kwiatkowski>"C:\Program Files (x86)\GoFiler Complete\GoFiler.exe" /RunScript:script.ls [/NoGUI]
If you are running a script from command line with the /NoGUI flag you do not actually have to specifically exit the application. When your script finishes executing GoFiler will automatically exit, unless the script returns ERROR_CANCEL. In the case of an ERROR_CANCEL return value the /NoGUI flag is reset and the application will open as if it had no /RunScript parameter. If you do not include the /NoGUI flag the application will remain open when your script finishes executing unless you have the script exit the program.
Knowing how to close the host application increases the versatility of Legato. It allows us to create separate processes and clean up after ourselves. We can also create tasks that are cleanup tasks before we quit the program (such as forcing every file to save and then quit - maybe even unregister - at the end of the day). This knowledge will allow us to end our scripts with finality, ensuring that the script completed its task. With this new-found knowledge we can even give ourselves a new title: The Closer, and know that at the end of the 9th inning we will be there to save the day.
Joshua Kwiatkowski is a developer at Novaworks, primarily working on Novaworks’ cloud-based solution, GoFiler Online. He is a graduate of the Rochester Institute of Technology with a Bachelor of Science degree in Game Design and Development. He has been with the company since 2013. |
Additional Resources
Novaworks’ Legato Resources
Legato Script Developers LinkedIn Group
Primer: An Introduction to Legato