Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

'C:\Program files' folder not recognized 4

Status
Not open for further replies.

SitesMasstec

Programmer
Sep 26, 2010
526
Brasil
Hi colleagues!

I use to distribute VFP9 applications inside InstallShield SETUP.EXE files to customers. In spite of the fact I advise them to change the installation folder to \INVOICES during the Setup installation, some users do not follow my instructions and install them in suggested folder (C:\Program Files\INVOICES\).

As my application has a folder \DATA inside the \INVOICES folder (\INVOICES\DATA), when the application has to read or save information in SYS(2003)+"\DATA\000001.DBF" it presents the error:

DO C:\PROGRAM FILES (x86)\INVOICES
"Program contains ubnrecognized phrase/keyword"


Problem is SYS(2003) cannot reflect C:\Program Files\INVOICES\ (where the user chose to install the application!)

Thank you,

SitesMasstec
 
Well, the easy solution is to put the file/pathname in double quotes:

[tt]DO [highlight #FCE94F]"[/highlight]C:\PROGRAM FILES (x86)\INVOICES[highlight #FCE94F]"[/highlight][/tt]

But you should also consider not putting INVOICES below PROGRAM FILES. Much better to keep the data and the executables separate, if only because you might one day want to run the executables from a local drive, but put the data on a shared server.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
spaces in file names...

DO ("C:\PROGRAM FILES (x86)\INVOICES\...")

I also don't know what you're saying about SYS(2003).

If you CD anywhere you are in Sys(2003), so DO SYS(2003) would need the current directory within the current directory, eg it would need C:\PROGRAM FILES (x86)\INVOICES\PROGRAM FILES (x86)\INVOICES but you surely don't have that repeated directory structure. If you want to use SYS(2003) in a command, combine it with SYS(5) to get the current absolute path SYS(5)+SYS(2003), specifying SYS(2003) only is the directory without drive and that is always seen as relative path from the current directory, not as path in the current drive, which it is. So either use no prefix at all to start in the current directory or use SYS(5)+Sys(2003) to use the current absolute path.

Bye, Olaf.
 
Problem is:

After the commands are executed in VFP command Window (or in my application) ...

MyFolder="C:\Program Files\INVOICES"
SET DEFAULT TO &MyFolder



... the following error is presented:
Invalid path or file name.

I think it is because the space between the words "Program" and "Files"

Thank you.
SitesMasstec
 
If you would read our earlier replies, you will see that it is exactly as you say: it caused by the spaces in the path name.

But that is not the root of your problem. If you hard-code a path name (in this case, Program Files), you are going to run into trouble if a future version of Windows uses some other path for executable programs, or if the user installs your application in some other location.

If you want the default directory to be the folder where you store your EXE program, then you should do this:

SET DEFAULT TO JUSTPATH(SYS(16))

If you want the default directory to be the one containing your data, then you should store the location of that directory in some form of non-volatile storage, such as the registry, or an INI file, or a config file of some kind, and then set that as the default.

And, as I said earlier, you should not place a data directory under program files.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hello!

Yes Mike, I indeed read the early answers, but I have used this for years and do not run into trouble:

MyFolder="C:\INVOICES"
SET DEFAULT TO &MyFolder

But when a user installs the program I developed and distributed, using InstallShield, the user may choose to install it inside his/her 'Program Files' folder. This is the problem. Visual FoxPro shows error when it executes this:

(The user may choose 'Program Files' or other folder during installation, so I cannot define SET DEFAULT TO "C:\Program Files\INVOICES")

MyFolder="C:\Program Files\INVOICES"
SET DEFAULT TO &MyFolder

MyBill=SYS(2003)+"\BILLINGS\B00001.DBF"

The solution I am using untill now is to advise the user NOT to choose installation in 'Program Files' folder.
Of course I may force the installation program installs in C:\INVOICES (here the problem is if the user can only install in a 'D' drive)

Thank you.
Sites Masstec
 
Your program, not VFP nor InstallShield, should guide the users to decide where they store the data. And your program should make sure that the data is NOT store in a subdirectory of Program Files.
 
Hello!

What tbleken said is what I was afraid to listen, but if this is the truth, I will adopt it (the user will have to install in the defined folder C:\INVOICES).

Thank you all.
SitesMasstec

 
SitesMasstec,
If you still insist to use "macro substition" (and not "name expression" which is here better) and to put program into "c:\Program Files" (which as you see could be problematic in many ways), you can use workaround - put one more layer string delimiters around the path(s) with space(s):

---------------------------------------
MyFolder=["C:\Program Files"]
SET DEFAULT TO &MyFolder
---------------------------------------

HTH
 
OMG, Slobodan! Why teach another bad approach, when we have already taught him the best way? Macros are BAD!!! ALWAYS!!! Name expressions are GOOD!
 
> but I have used this for years
Well, but C:\INVOICES doesn't have any space in it. If you execute such code with a value containing spaces for the first time, then it doesn't work and you simply were lucky all the previous years.

It's as simple as this: Macro substitution substitutes (replaces) the variable name with its value and then executes that:

If you do MyFolder="C:\Program Files\INVOICES", then the value of the MyFolder variable is C:\Program Files\INVOICES, not "C:\Program Files\INVOICES", the double quote characters are delimiting the string, that's why they are called string delimiters, they mark begin and end, the string value begins after the first double quote and ends before the second.

So SET DEFAULT TO &MyFolder after the substitution means SET DEFAULT TO C:\Program Files\INVOICES, not SET DEFAULT TO "C:\Program Files\INVOICES". If you execute ? MyFolder you aso only get C:\Program Files\INVOICES printed on the screen, without the double quotes. And the compilation of te command SET DEFAULT TO C:\Program Files\INVOICES is failing, because all clauses, options and values specified within in a command are space separated. The first space in a file name is ending the file name and making the compiler see the part after the space as another clause, option or value of the command, in this case no further such part is expected, so it's triggering an error and reported as an unknown and invalid clause.

It's obviously no solution to SET DEFAULT TO MyFolder, as that would interpret MyFolder literally as a folder name and most probably not find it, so the way to specify you want a variable value as the parameter value of a command is surrounding it with brackets making it a name expression: SET DEFAULT TO (MyFolder).

The same applies to many commands like SELECT, USE, any IN clause, any part of a command being kind of a parameter value. It's the same thing in DOS, the core reason is spacesd are separators.

Even if you don't know name expressions are done with brackets, you should see what macro substitution does and how it can't work with file names including spaces. The simplest other thing you could do is surround the macrosubstitution with string separators: SET DEFAULT TO "&MyFolder", simply because putting in the value of MyFolder now puts it inside string delimiter double quotes and that also works. The same goes for what Slobodan suggests, he simply used other string delimiters [ and ] to put the normal double quote delimiters inside of the string as part of the string value. Then the macro substitution also contains the double quote characters, which finally act as delimiters. But name expressions are not only one charater shorter, they don't need an additonal compilaton after the substitution. Even if you ever consider using the double string delimiting, don't do it when populating the variable value, let it surround the macro substitution, that makes it easier to understand what's going on.

One thing is sure: You can't insist on this to work, just because it worked for so long. It never was correct, it always depended on the location being in a folder without spaces in its name.

Bye, Olaf.
 
Hello colleagues!

I think I failed to make clear that:
I DO NOT choose to install a program (through SETUP.EXE file) in a folder inside the "\Program Files" folder. The users DO!

But as you all, specially Olaf, explained the problem with this approach (permitting the user to choose where to install the application I distribute) I made the decision to configure InstallShield to install the file in a pre-defined folder, for exemple C:\INVOICES, not permitting the user to change it.

Thank you all,
SitesMasstec
 
Well, you can solve this problem this way, but you can also program in a way to cope with such installations, you should be able to cope with it as the program files folder is the normal installation destination for applications anyway and is protected against simple write access unless users are having admin permission/elevation and turn off UAC. Since you now know, you could fix it in your code rather than in taking away the installshield option.

Bye, Olaf.
 
You shouldn't be telling users where to install the application. Your application should work wherever users install it.

Tamar
 
Hello Tamar!

Ok, but if I let the user installs my application (SETUP.EXE, generated by InstallShield) in the "Program Files" folder, I cannot use this inside my application:

YRFOTO=SYS(2003)+"\FOTOSREC\"+"R001.JPG"
IF .NOT. FILE ("&YRFOTO")
EMBRANCO=SYS(2003)+"\FOTOSREC\FOTONAOD.JPG"
COPY FILE &EMBRANCO TO &YRFOTO
ENDIF

since SYS(2003) will be, for example C:\Program Files\INVOICES\ and Visual FoxPro doesn't undestand the space between "Program" and "Files". An error is shown.

Thank you,
Sites Masstec




 
if I let the user installs my application (SETUP.EXE, generated by InstallShield) in the "Program Files" folder, I cannot use this inside my application:

Then you should not use that inside your application. Full stop.

(And it actually can work if you'd do it the right way, as has been explained on this thread.)

 
Even if you force installation into a folder without spaces in its name, SYS(2003) is not the application folder, it's the current folder, and it can be set from outsidee of the EXE by setting the working directory of a shortcut. So again: Adjust your code. The single thing to do is use (file) instead of &file in any file related commands. Is that too much work? Or don't you have source code and your only control is making a setup with the EXE given as is? That would make me wonder how you came across SYS(2003)+"\DATA\000001.DBF" without having source code.

In VFP9 Code REferences will help you find all places to modify and in previous versions you may use the GoFish search utility you may still find at Universal Thread Download section.

Bye, Olaf.
 
Hello Olaf!

I wrote the complete source code.

Let's see my application that will be installed in the \CUSTOMERS folder, for example.

So the user probably will install it inside the 'C:\Programs Files' folder. Ok, so the user will have the application instaled in C:\Programs Files\CUSTOMERS. This is fine.

But the application has another sub-folder inside C:\Programs Files\CUSTOMERS: \PHOTOS, which will store a lot of JPG pictures of the customers. So we will have C:\Programs Files\CUSTOMERS\PHOTOS. That's fine too.

Problem is:
I give commands to the application to store the photo of customer which code is 42 to P42.JPG, 100 to P100.JPG, etc, in the sub-folder \PHOTOS
The current folder, where the application is running is C:\Programs Files\CUSTOMERS.
IF I want to see the picture of the customer which code is 200 the application must search for it NOT in the current folder but in the current folder+\PHOTOS. This is the reason for:
Anyname=SYS(200)+"\PHOTOS"
IF .NOT. FILE ("&Anyname")
...

Thank you,
Sites Masstec
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top