1
votes

I'm porting an old FoxPro app to Visual FoxPro. The old program of course did not use any classes, but I've started to use them for certain cases. This has caused a problem in the development cycle that I don't see mentioned anywhere.

Basically, if I create an object based on a class defined in a procedure file, then FoxPro will never let go of my APP. I can't delete it or rebuild it, and I have to restart VFP every time I make a change.

Steps to reproduce. Make a.prg with

SET PROCEDURE TO b
m.test1 = CREATEOBJECT('TestClass')
RELEASE m.test1

and make b.prg with

DEFINE CLASS TestClass AS Control
ENDDEFINE

Create a project called a:

MODIFY PROJECT a

And add the program a.prg. Then

BUILD APP a FROM a
DO a.app
DELETE FILE a.app

The last line will give

Application file 'c:\...\b.fxp' is not closed

Then if you try the DELETE again, it will say

File access is denied c:\...\a.app

I can see in Process Explorer that vfp9.exe has a handle on the APP file that never goes away until I quit FoxPro, no matter what I try:

  • SET PROCEDURE TO
  • CLOSE ALL
  • RELEASE ALL
  • CANCEL
  • CLEAR ALL
  • ad nauseum
4
I am using VFP 7 and you can't issue a build app a from a command becuase it will throw a file a.pjx does not exist error. Do you have a a.pjx file? Perhaps version 9.0 is different?DaveB
@DaveB, thanks for trying this. I forgot to mention that I created a project "a.pjx" and added a.prg. You have to do that interactively (i.e. it can't be scripted).harpo

4 Answers

1
votes

Try the CANCEL Command.

Ends execution of the current Visual FoxPro program file. Control returns to the Command window when Visual FoxPro is being used interactively. If a distributed run-time application is running, CANCEL terminates the application and control returns to Windows. If a program is executing in Visual FoxPro during design time, CANCEL terminates the program and control returns to the Command window.
Executing CANCEL releases all private variables.

0
votes

I don't see CLEAR ALL among the things you tried. My standard clean-up is:

CLOSE ALL
CLEAR ALL

Tamar

0
votes

The solution is

CLEAR CLASS TestClass

(which incidentally is not indexed in the help file).

In the real app, I've had to carefully script the release procedures so that I can recover from this state in the event of an error. But CLEAR CLASS was the missing link.

0
votes

I did what you had almost verbatim... only change was in a.prg

SET PROCEDURE TO b
m.test1 = CREATEOBJECT('TestClass')
RELEASE m.test1
SET PROCEDURE TO   <-- I Added this line

In addition, your attempt to DELETE A.App WOULD have failed... Unless it was an oops.

DELETE is a command to delete records from a table. I THINK you meant ERASE a.App Because no table was available, it couldn't act on the DELETE command and may have been giving you a misdirected message. But by putting the closing "SET PROCEDURE TO" at the end of the "a.prg" allowed it to properly close and erase the a.app file when finished.