No, I never used that mechanism, though I worked with MSDOS, I wasn't a developer at that time, I knew things like memmaker, but I didn't use the original Foxbase and FPDOS.
Regarding clean.prg the simplest way to get to a clean environment is a restart, I have this PRG in Home()
Code:
_Screen.Tag = On("Shutdown")
On Shutdown VfpRestart()
Quit
Procedure VfpRestart()
On Shutdown
cCommand = _Screen.Tag
cHere = Sys(5)+Sys(2003)
If !Empty(cCommand)
&cCommand
Endif
nRestartBegin = Seconds()
oVFP = Createobject("VisualFoxPro.Application")
oVFP.Visible = .T.
oVFP.DoCmd('_Screen.WindowState=2')
oVFP.DoCmd('CD "&cHere"')
oVFP.DoCmd('Public nRestartBegin, nRestartEnd')
oVFP.DoCmd('nRestartBegin= '+Transform(nRestartBegin))
oVFP.DoCmd('nRestartEnd= Seconds()')
oVFP.DoCmd('? "Restart took", nRestartEnd-nRestartBegin')
oVFP.DoCmd('Release nRestartBegin, nRestartEnd')
Quit
Endproc
I also have VFP on a RAM disk I load on system start, for that I made a RAM disk image (depends on what RAM disk software you use), that loads as drive F: and has F:\VFP9. I linked the original Home() to F:\VFP9 via mklink.
To do that start cmd.exe as Admin, CD into system32 and then do mklink /J "C:\Program files (x86)\Microsoft Visual FoxPro 9" "F:\VFP9" (or whatever is Home() in your case).
Before you can do that junction the original home folder has to be renamed to "Microsoft Visual FoxPro 9 Backup", for example. It will now not be used any more, but you might want to keep it to go back to it, though the RAM disk image also makes each restart a reset. You'll have foxuser.dbf in your user profile and other settings in the registry, so changes you make are still set as defaults and there is almost no difference to how VFP works. If you do changes to sample data in the samples folder, that will get reset at a Windows restart, for example.
My RAM disk only needs about 256 MB and I sized it to 320MB to have a little wiggle room when VFP writes something into Home() like an fxp at build of something.
The mklink makes it transparent to anything else, you can use a shortcut you made to VFP9 as is without changing anything, as access to the old home() folder is redirected by the junction.
You can adapt this to your needs, like I did by keeping the current directory from the current to the next VFP session. You can also RUN \N vfp9.exe instead of using the VisualFopro.Application class, then you have the opportuniity to use command line parameters.
The code posted records timing of the restart and from nRestartBegin = Seconds() to oVFP.DoCmd('nRestartEnd= Seconds()') takes 0.2 to 0.3 seconds on my system. I don't have the section after CD cHere in my usual PRG, that's just for demonstration purposes.
Restarting VFP and QUITting the current ID session ideally would be done by first quitting to write flush changes to foxuser.dbf, etc. But the VFPREstart procedure executes whatever you or a framework forsees as last VFP session action by ON SHUTDOWN and also a QUIT runs through any objects Destroy() event, etc. You might even stop quitting VFP, but you'll still get a new VFP session. That might then fail to load a project or get exclusive access to other files, but in the usual case that shouldn't be a problem and if you need to do any special calls you can embed them in the VFPRefresh() procedure.
I guess you won't even need a RAM disk to do this, you can also use the Windows Disk Management to create a vhd or vhdx (at least in Win10 that's on board). With which you don't put VFP into RAM, necessarily, but a virtual disk drive that also profits from filesystem write buffering, so if you let that always start empty and copy HOME() into it after you attach it, VFP should mostly be cached. You could also have almost all of VFP in the vhd(x) image and at start only copy over vfp9.exe as that needs to be cached to start faster. It's a bit of a hack and means your first start takes longer.
But then there are several advantages: You start from always the same image. If you run VFP as admin, that elevation is kept for the new VisualFoxpro.Application instance without the need to confirm a UAC prompt again. You can do whatever you want in the VFPRestart() routine, before anything of the current session unloads through the final Quit command. If you care much for tidying code that saves and then also verifies saved data, that could be done in Destroy() or here. And since you have access to anything you can transport not just the current directory but anything else you want to forward to the new VFP session except objects themselves. But the idea is to refresh all memory and restart any framework, remove any classlibs, classes, prgs and such stuff from memory.
Also, you can manage user licences with such a VHD or RAM Disk image and keep it in the hands of the developer. In that case you also would like to migrate several things into the Home() folder that becomes the RAM disk or vhd image, of course: The VFP runtimes in Microsoft Shared and the msvcrt71.dll from SysWow64, to name two things. Anything that needs to be done to the current Systems registry and establishing the junction with mklink could also be done at the step of attaching the image.
And now, you obviously could ensure SET DEVELOPMENT is set ON within the VFPRestart procedure or do other things. What you don't need and what only matters in terms of getting file access to unclosed handles is to do any CLEAR, RELEASE, USE, etc. as that's all done by a successful QUIT. I never had any need to have the same _VFP.ProcessID or _VFP.ThreadID, those are two of very few things that have to change by starting the new session.
Chriss