Just one detail, as you recently also asked about data sessions.
This is not closing all database file usage when you have multiple forms using multiple - each private - data sessions.
But the need to close anything doesn't exist, when a VFP app closes it isn't just ending the process. What still done, also when you do ExitProcess, is the unloading of the vfp9r.dll, the FoxPro runtime that always starts first and also is unloaded last. That's simply triggered by the general DLL unloading process of Windows when a process ends. And you don't have to do anything about it.
Using data sessions, table closing is inbuilt into releasing a form as it also ends the data session that belongs to it, unless the form worked in the gobal default data session. But ending the process you end all forms and trigger all kind of closing processes, closing all files to which your process had explicit or implicit handles etc., including the global default data session.
Code closing files only is important to do so with more own control. Mainyl about the point in time and the order. That's why doing a shutdown is not a good move. Besides affecting all other processes on that computer, that's not just a topic of VFP.
To stick to the data session and more important the visual data environment of a form (an SCX, not a PRG based form class), this data environment has your tables in the visual section and they are not only opened when the form starts, they are also closed when the form releases. The D does not only implement initialization also the unloading. So there's actually nothing to do for you unless you find out something blocks the release of a form. That can happen, for example, by transactions not ended. Nevertheless I'm sticking to it, you can actually cook, eat and the dishes are done automatically. Even transactions are automatically closed, just usually by rolling them back, not committing=saving. And they can actually affect other users not getting file access as long as the transactions linger. That is the motivation for doing rollup code in VFP that closes tables and other files, commits transactions or rolls them back.
A VFP application also ends at the end of the main.prg. There does neither need to be an ExitProess a Quit, no Cancel, not even a Return. The last line of the main.prg ends the vfp process just like the last line of a method causes the return to the caller or to the READ EVENTS, if it wasn't code calling but an event happened. Again, we discussed this topic a lot recently in thread184-1817628. That was not your thread, but you posted and stated you read it, too. The use case for ExitProcess mainly is to have an administrative way out, and as much as I talked through many points, it's true the usual ending of a VFP application is by CLEAR EVENTS, in turn going to what is after READ EVENTS (unless a modal state like a MessageBox hinders that) and then exiting, when all code after Read events is done. And that includes the standard case that there is no code after READ EVENTS at all, or only class and function/procedure definitions that are not executed unless explicitly called.
Just to stress this out once more, CLEAR EVENTS actually ends READ EVENTS, code then continues from there onwards and that ends VFP. RETURN TO MASTER, as I explained in that thread, can cause the same as CLEAR EVENTS and can indeed interrupt an infinite loop, where CLEAR EVENTS doesn't have full power to end whatever currently runs and return after READ EVENTS. It's not a usual issue and therefore you don't usually need or do ExitProcess. Nor do you shutdown the computer. The end of a VFP process is just actually getting to the end of code. And READ EVENTS is just a stopper, a command telling VFP to stick to that line until events happen, which include any mouse or keyboard inputs, clicks, pasting, ole drag & drop, menu usage. Which also is the reason an application without READ EVENTS ends, because, well, it ends. Surprise, there is no more code to do, then good bye, I'm gone, finish, end.
People forget READ EVENTS or perhaps better said learn about READ EVENTS first, because the IDE is usually the thing that keeps the VFP IDE running when main.prg already ended. And so your nonmodal forms also keep running and an application seems complete and ready to build and deploy. Yet compiling and starting the built EXE what you removed is the command window and IDE, so getting to the end of main.prg ends the EXE. That's what I thin everybody has experienced in VFP usage.
So the only reason for writing code wrapping things up, closing all workareas, etc. is to get things done in the way and especially in the
order you want them done. If you don't care and don't need to care, then also don't write such code.
If you have problems ending a VFP process, then it's likely a hurdle you built into a single form, a single class and have not programmed the end of each single thing the way it should be. Every Init() also has a Destroy(), that's the event for tidying up what hasn't already been done and that's the principle of self care. And it's the cleaner and in detail always easier way. People just think about general end code to catch anything missed in each special single case. It's overwhelming to write all destroy code, if you never did just even one of them, but to give a stronger reason, even when you use QUIT as quite similar "hammer" to end VFP as ExitProcess is, you still run through any forms QueryUnload, Unload, and Destroy event. It's also the main reason a form is a bit more complex in ending, you have three events, not just the Destroy. Take a look into that in the help.
By the principle, if anyone cares for themselves there is no need for a central carer, ever object should also tidy up about itself and only need to care for others, for child objects, if they are not programmed to care for themselves. And what do you put into Destroy events? The good news is: Most of the time nothing, you didn't forget much. Forms end their data session, for example. Ask yourself that same question what to do in Destroy, whenever you start something in any code anywhere. In some cases you process something from start to end, you already finish with it even within a button click, then there is nothing to do for destroy. In other cases you generate query results to display them and surely not close them right away. At some point it will be. Always think in brackets. You open something, it needs to close somewhere.
Chriss