Welcome to Foxite.COM Community Weblog Sign in | Join | Help

The importance of Paths in VFP

One of the commonest problems that I see in on-line forums is related to how Visual FoxPro works with files. In this respect the project manager is both a blessing and a curse! A blessing because, as long as we work through the project manager, it handles the issues associated with finding and opening files for us. A curse because we tend to forget that VFP does require paths internally. A common question is, therefore something along these lines:

The answer is, of course, that VFP  has not been given a search path. Although I have never seen this documented formally it seems that VFP takes a pretty rigid approach when asked to find something. For example when you call a function VFP first checks the currently executing program, then other programs in memory, then the current working directory, then directories on its own search path and finally the Windows Search Path. Similarly, when looking for a unqualified table name (e.g. USE account, as opposed to USE C:\Myfiles\account.dbf) , it looks first in the currently selected directory, then along its own search path and finally along the Windows search path.

Notice that directories on its own search path are always checked before any operating system level path. The significance of this is that when you give VFP its own search path it will find files without ever having to go to the operating system path – clearly this will be much more efficient since the path need only include those places that are strictly relevant to VFP.

The Default Directory

In the absence of any other information Visual FoxPro uses the currently selected drive and directory as its 'path' and you can always restore this setting by simply issuing:

SET PATH TO

However for more sophisticated applications, and certainly for development, you will have some sort of directory structure and you should always set a proper search path to include all required directories. The first thing to do is to set the default directory and there are several ways (as usual) to do this:

·         Specify a default in the Configuration File using DEFAULT = <path to directory>

·         Set the default directly in code using SET DEFAULT TO <path to directory>

·         Change to a directory using the CD <path to directory> and issue SET PATH TO

To change the default directory interactively use: SET DEFAULT TO ( GetDir() ). (The 'CD' (or 'CHDIR') command can also be used to change both drive and directory to the specified location).

Gotcha! LOCFILE() changes the path

Note that generally using the “Get” or “Put” functions (e.g. GetDir()) does not change either the default directory or the path. The exception to this rule is an apparently un-documented (in VFP) feature of the LOCFILE() function which does add the selected directory to the VFP search path as the following code shows:

*** Clear any path
SET PATH TO
? SET( ‘path’ ) && Returns nothing
USE LOCFILE( ‘account’ )  && Locate the file
? SET( ‘path’ ) && Returns C:\Projects\Data

This behavior has been part of the language since at least FoxPro 2.6W and, interestingly, it is documented in the FP2.6W Help file where it states that:

The Open dialog can be used to locate the file.  When a file is chosen from the dialog, the file name is returned with the file's path, which is appended to the FoxPro path.

However, it appears that in creating the VFP help file the last phrase got lost and it remains missing from the help in VFP 9.0 (below) even though, as we have seen, the behavior certainly still applies:

The Open dialog box can be used to locate the file. When a file is chosen from the Open dialog box, the file name is returned with the file's path.

Using the SET PATH command

Setting the path is simplicity itself. Just issue the SET PATH command followed by a list of the directories that you wish to include. You do not need to fully qualify subdirectories – separating them with either commas or semi-colons is sufficient. The example shows a typical Visual FoxPro search path:

SET PATH TO G:\VFP90;C:\VFP90\PROJECTS\;DATA;FORMS;LIBS;PROGS;UTILS

To retrieve the current path setting you can use the SET() function (which will work with most of the Visual FoxPro SET commands) as shown below. You can assign the result directly to a variable or, as shown below, directly to the clipboard so that you can then paste the current path into a program or documentation file:

_ClipText = SET( 'PATH' )

Visual FoxPro allows the use of both UNC path names, like:

\\SERVERNAME\DIRECTORYNAME\

and allows the use of embedded spaces (when enclosed in quotation marks) in directory names like:

"..\COMMON DIRECTORY\"

However, while the latter may be allowed, I subscribe to the principle that 'although you can use embedded spaces, arsenic is quicker.' (The same, by the way, applies to file names with spaces!) While improving readability, spaces can also cause problems when trying to handle files and directories programmatically and I still feel that the best advice is to avoid them wherever possible in applications. For example, the following code works perfectly well for conventional directory names, but will fail if the selected directory contains embedded spaces:

LOCAL lcDir

lcDir = GETDIR()

IF ! EMPTY(lcDir)

  SET DEFAULT TO &lcDir

ENDIF

VFP 9.0 introduces the ADDITIVE clause to the SET PATH command to enable path fragments to be added dynamically(interestingly this is what LOCFILE() has always done anyway).

Determining the Current Settings

Fortunately, Visual FoxPro provides us with a number of functions that will help us locate where we are at any time:

·         SYS(2004) returns the directory from which Visual FoxPro was started but in a distributed run time application, this will always be the location of the runtime DLL (which is normally the appropriate version of the Windows 'System' directory)

·         HOME() returns the directory from which Visual FoxPro was started by default, but has a number of additional useful options

·         _VFP.FULLNAME accesses a property of the Visual FoxPro application object that contains the full path and file name which was used to start VFP

·         FULLPATH('') or FULLPATH( CURDIR() ) returns the full drive and directory of the current working directory (including the terminal "\")

·         SYS(5) returns the default drive (including the ':')

·         CD (only works interactively in the command window) shows the current drive and directory in the current output window – but will also change drive and directory in one single command

·         CHDIR will change to the specified Drive/Driectory (just like CD) but will not report the current status (and so does not mess up your forms)

·         CURDIR() returns just the current directory (with terminal '\') but not the drive

·         SYS(2450) introduced in VFP 8.0 controls whether an application searches internally before accessing the external search path

Setting The Path

I usually use code of the following type in my startup programs to ensure that I always have the appropriate paths set – whether running in development mode, or in a compiled EXE.

IF VERSION(2) = 0
  *** Runtime Start, VFP Startup + Current Directory + "\DATA" only
  lcPath = HOME() + ";" + ADDBS( FULLPATH( CURDIR() )) + "DATA"
ELSE
  *** Design Time startup - full development path
  lcPath = HOME() + ";" + ADDBS( FULLPATH( CURDIR() )) + ";FORMS;LIBS;DATA;PROGS;UTILS"
  *** We want asserts ON in Dev Mode
  SET ASSERTS ON
ENDIF
SET PATH TO (lcPath)

Note that this differentiates between the full paths needed for Development and the reduced path used for a runtime implementation

 

 

Published Monday, March 21, 2005 1:50 PM by andykr

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: The importance of Paths in VFP

Monday, March 21, 2005 11:20 PM by Jamie Osborn
One thing that I have noticed, since VFP8, is that an non-existent path in your SET PATH can really slow down your app. It seems that VFP (and whatever API it is calling), really has a good look for the non-existent path.

I noticed it when I had a dud path in an app and that app suddenly ran like a dog when compiled in VFP8.

# re: The importance of Paths in VFP

Wednesday, March 23, 2005 1:22 AM by Andy Kramek
Interesting, I wonder why that should be. Are you sure this is a VFP issue rather than OS? For example I have noticed this type of problem routinely under XP but not under Win2K.

# re: The importance of Paths in VFP

Wednesday, March 23, 2005 7:58 PM by Brian Vander Plaats
>> CD (only works interactively in the command window)<<

I've actually used CD in a program file before...

Also, have you noticed different pathing behaviors when working with FoxPro DLL's vs Exe's? I recently created a small web service, that needed to use a table in the same directory as the dll. Typically when I do this with exe's I can simply reference the table by name, without needing a specific path. But when I tried this in my Web Service, it didn't work, because the path was pointing to the windows folder (system 32 if I remember), not the directory the DLL was located in. I ended up having to set a specific path to this file, which isn't ideal, because I need to know the location of the table when I am compiling the DLL.

# re: The importance of Paths in VFP

Wednesday, March 23, 2005 11:30 PM by Andy Kramek
> I've actually used CD in a program file before...

Really? How did you do that - I always got a syntax error...

> Also, have you noticed different pathing behaviors when working with
> FoxPro DLL's vs Exe's?

Check out "_VFP.ServerName" property - it will give you the starting location of a DLL or EXE at run time (the quivalent of CURDIR())

# re: The importance of Paths in VFP

Thursday, March 24, 2005 4:41 PM by Malcolm Greene
Great blogs! I really enjoyed your first 2 posts.

I'm wondering if you or any of your readers has experience tweaking sys(2450)? In other words, is there any reason why you wouldn't want to override the default behavior at the beginning of your applications via sys(2450,1)???

I'm curious to hear if anyone has done any benchmarks or discovered any gotchas.

My understanding is that sys(2450) should make the typical self contained APP/EXE significantly faster as all function/method references are resolved using the internal function tables vs. searching the SET PATH list of folders on every function/method reference. This sounds a lot faster to me.

I would also think that changing the default behavior of sys(2450) will make an application more secure because a malicious user can't create a code injection scenario by creating FXP files with names that match application functions and placing these FXP files in an application's path or root folder as a technique for hijacking an application.

After mulling over the benefits of SYS(2450) I'm wondering why there hasn't been more discussion of this function and why we as a community aren't aggressively encouraging developers to change this function's default setting?

# re: The importance of Paths in VFP

Thursday, March 24, 2005 9:55 PM by Andy Kramek
>> In other words, is there any reason why you wouldn't want to override the default behavior at the beginning of your applications via sys(2450,1)???

Only if you rely on the ability (as many people do) to distribute updates as stand-alone PRG/FXP/VCS files. I have at least one application that I work on that uses a stub loader to intialize the run-times, and then executes FXP files directly. Not the best architecture but it is easy when you have a high maintenance (especially when it's also old!) application.

>> After mulling over the benefits of SYS(2450) I'm wondering why there hasn't been more discussion of this function and why we as a community aren't aggressively encouraging developers to change this function's default setting?

Dunno! Unless the practice of using FXP directly is more widespread than we think...<shrug>

Why not post the question on Steven Black's Wiki (http://fox.wikis.com)

# re: The importance of Paths in VFP

Friday, March 25, 2005 2:10 AM by Malcolm Greene
Andy,

I think(?) your loader based apps should still work as expected because sys(2450,1) will still search for your main components in the search path - it will just search your loader first. If you loader is just a simple loader then there should be no difference.

I'll carry this discussion over to Steven Black's wiki.

Malcolm

# re: The importance of Paths in VFP

Monday, December 05, 2005 11:28 PM by anabisbe@amby.net
Thanks Andy !!

You can find the Spanish version of this article at (Puede encontrar la versión en Español de este artículo en:)


http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=70

Regards / Saludos,

Ana
www.amby.net
www.PortalFox.com

# re: The importance of Paths in VFP

Monday, January 23, 2006 8:35 AM by 机票

What do you think?

(required) 
required 
(required)