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!

Run command works When IT wants to...

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi,

Using VFP9sp2 on Win8 and on the same desktop session as an administrator, I'm getting varied results using the run command.

gcFileName = 'e:\folder\sub folder\another folder\100\1.tif'

Run /N2 Attrib -r &gcFileName - worked when testing when I created it, and now it doesn't change the attribute, and it does not error.

Just now I tested these three iterations, and it still will not change the attribute.
Run /N2 Attrib -r '"' + (gcFileName) + '"'
or
Run /N2 Attrib -r '"' + &gcFileName + '"'
or
Run /N2 Attrib -r (gcFileName)

If I use the OS's command window, it works as expected by typing...
Attrib -r "e:\folder\sub folder\another folder\100\1.tif"

I haven't closed the session yet because I'm keeping its current state in the debugger open while testing for a fix.

The file is not open as I can delete it with Windows explorer, then add it back and set its attribute to RA, and when setting the "set next line to" in the debugger to it and execute it again, it still fails...

What can I do to test and fix this?

Thanks,
Stanley
 
Not sure what's happening unless it's a rights issue.
Have you tried enclosing the entire command line in quotes?
Code:
STORE "Attrib -r " + '"' + gcFileName + '"' to cCommand 
Run /N2 &cCommand


-Dave Summers-
[cheers]
Even more Fox stuff at:
 
Stanlyn,
Can you check the files with the ATTRIB at command line, and verify if either S or H are on? If they are, DOS (I can't believe I just said that) will not act on the -R attribute on it's own. You have to issue -r -s -h and then reapply the /s/h if you still want them to be there.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Sorry, that should have been reset them with +r+h not /.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Hi Dave,

I done it your way originally when initially creating and testing it and finally reduced it down to the way I posted and both ways worked as expected. And now it quits working as expected, hence this thread.

So, I guess its time to end the vfp session, restart vfp and see if it still fails or works. And, if it fails I'll retry it back to your way and see, and report back.

Thanks,
Stanley
 
Hi,

While still in the debugger session where the issue resides, I changed the filename by removing the 2 spaces within the name. I then removed the spaces from the 2 folders that had spaces within, so the path would be valid. I reset the "set next statement" and it worked as expected, so the issue is with the embedded spaced withing the os path and filename...

But that doesn't explain why these two items failed, as I added the double quotes to the path being passed to the run command as in... Both of these line failed earlier...

Run /N2 Attrib -r '"' + (gcFileName) + '"'
or
Run /N2 Attrib -r '"' + &gcFileName + '"'

Any idea?
Stanley
 
Make the " part of gcFilename and then macro sub it.

So gcFilename = '"'+ALLTRIM(gcFileName)+'"'

RUN/N2 ATTRIB -r &gcFileName


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
OK,

I think I'm past that that issue and while running these next 2 lines in the debugger they run fine. If I allow it to run full speed it errors with a "cannot create file" error #1102 when copying.

lcOutFile = Strtofile(Filetostr('a.tmp') + lcKey1, 'z.tmp', 0)
Copy File 'z.tmp' To (gcFileName)

Is there anything like a flush as it appears that the strtofile function has not finished before the copy command runs. Slow it down and it works. I really don't want to put in any un-necessary slowness via hard coded wait states or inkey() values. I tried adding a DoEvents right before the copy command and that did not fix it.

Any idea?
Stanley
 
I do this all the time, with no issues at all on a screaming fast machine... BUT I notice something odd in your statements.

Why are you converting a file to string (FILETOSTR) and then immediately converting the string back to a file? Why not just copy the file to another file? You can rename on the fly, so long as the full path is qualified. That approach seems odd to me, and may be where your issue is.
Or...
Break the statement into two. Issue the FILETOSTR first, and then take that output and STRTOFILE it.

Otherwise, you could simply COPY FILE 'a.tmp' TO 'z.tmp'

I don't see your code adding anything to the file? (Though the value of lcKey1 is not clear to me).

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Hi Scott,

>> I don't see your code adding anything to the file? (Though the value of lcKey1 is not clear to me).

The lcKey1 is a string of text that is added or removed from the end of the file so I can know if the file has been base64 encrypted, or not. This is necessary to avoid encrypting the file again and all the libraries I've looked at doesn't have a way to detect if the file was encrypted. Instead they all suggest you rename the file to indicate its status. I needed a way to look at the file's contents and make that decision. If it doesn't have the string I'm looking for in the file's last 10 characters, then its not encrypted. If the string exists, and I wish to decrypt it, I first remove the last 10 chars, save it back and then decrypt the file. If the file is not encrypted and I wish to encrypt it, I first encrypt it and then add my string of 10 chars to the end of the file. I've run tests over 8 iterations involving 400,000 records each and its quick and reliable. The only downside it has is its limited to VFP's 16mb strings limitation. And, my test subjects have been .bmp, .avi, .pdf, .wav, .dbf, .mpg, .mp3, .doc, .xls, .jpg, plus many other file types.

The last changes where I've added more error checking such as if the file is readonly, was it deleted before the file gets processed, and etc... is where it got broken.

So, its good to know that the speed is not a factor here, even thought it appears to be.

I know I can use low level fopen and set reprocess until I get a handle, then release the handle, but that is like using a sledge hammer to drive a tack...


>> Break the statement into two. Issue the FILETOSTR first, and then take that output and STRTOFILE it.

I do not believe the issue is there as I've ran that line unchanged in testing on about 3.2 million records (8 iterations on 400,000 per iteration) and all without a hitch... That's what is frustrating, it passed all those tests and now acting up...

What would you try?

Stanley
 
Hi,

Would this testing for readonly place a lock of any kind using the way I'm doing it?

=Adir(laFN, gcFileName)
llReadOnly = 'R' $ laFN(1,5)

Stanley
 

If I put in inkey(.03) or more it works as expected. Inkey(.01) and .02 fails the same as not having the inkey there... I've included the entire Encrypt function here...

Code:
Procedure FileEncrypt
	lnSuccess = goCrypt.CkEncryptFile(Alltrim(lcFP), 'a.tmp')

	If (lnSuccess <> 1)
		=Messagebox(goCrypt.LastErrorText, 0, 'En-Cryption Error', 30000)
		llEncFailed = .T.
	Else
		llRetry = .T.
		lnTryCount = 0
		llReadOnly = .F.
		llResetReadOnly = .F.

		Do While llRetry = .T. .And. lnTryCount < 10
			llRetry = .F.
			lnTryCount = lnTryCount + 1

			=Adir(laFN, gcFileName)
			llReadOnly = 'R' $ laFN(1,5)

			If llReadOnly = .T.
				Store "Attrib -r " + (gcFileName) To cCommand
				Run /N2 &cCommand
				* Run /N2 Attrib -r &gcFileName
				llRetry = .T.
				llResetReadOnly = .T.
			Else
				Delete File (gcFileName)
				Exit
			Endif
		Enddo

		lcOutFile = Strtofile(Filetostr('a.tmp') + lcKey1, 'z.tmp', 0)
INKEY(.03)
		Copy File 'z.tmp' To (gcFileName)

		If llResetReadOnly = .T.
			Store "Attrib +r " + (gcFileName) To cCommand
			Run /N2 &cCommand
			* Run /N2 Attrib +r &gcFileName
		Endif

		Delete File 'a.tmp'
		Delete File 'z.tmp'
	Endif
Endproc

Any other ideas on why I have to slow it down for it to work?
Stanley
 
Run has a special thing to think about

>Run /N2 Attrib -r (gcFileName)

This is the version of the command, which would work in VFP, but RUN rather forwards averything after the /N2 or some other options to command.com or whatever is configured in COMSPEC.
You can use macro substitution with run, as macro substitution always first triggers VFPs substitution and compilation of the substituted command, but the name expression with brackets is forwarded to the DOS shell 1:1. You are making this part of the ATTRIB command and that has it's own rules, ATTRIB and all dos commands don't know name expressions but have the same problem of spaces in paths and filenames. The same goes for SQLEXEC, you can't use a name expression inside sql you send to a remote database, it's executed there, not inside VFP. This is the extra thought to put into RUN or anything else calling something outside of VFP.

And the name expression itself does not cause a substitution with "the file name" before it's forwarded, so the Sttrib command really gets (gcFileName) literally as it's parameter. Dave Summers shows a good way to cope with all this by putting together the DOS command stringg fully including quotation marks and then finally using one macro subtitution.

Bye, Olaf.
 
Thanks Olaf for that...

Now, does vfp's "delete file" and "copy file" commands pass their work off to command.com and is subjected to the same rules as "run"? I ask because the issue I'm now having is having to insert an inkey(.1) just after the strtofile command and before the "copy file" command. Previously I thought an inkey(.03) was the minimum, and I've had to increase it to (.10). This whole inkey(xx) thing is undesirable, but without it I immediately get the "cannot create file" error 1102. If I take the inkey out and step thru it via the debugger, then no problem, it works fine.

Any idea?
Stanley
 
Well, looks like we have a fix, thank you all! The issue and fix goes back to Olaf's explanation and Dave's code. So far, it is working and about to let to process a whole group. The changes are below and it does appear that vfp's copy and delete commands are subjected to the same rule as the run command. And notice the commented out lines that were previously used when the error occurred.

Code:
				Store "Attrib -r " + '"' + (gcFileName) + '"' To cCommand
				Run /N2 &cCommand
				llRetry = .T.
				llResetReadOnly = .T.
			Else
				Delete File '"' + (gcFileName) + '"'
				*Delete File (gcFileName)
				Exit
			Endif
		Enddo

		*INKEY(.1)
		Copy File 'a.tmp' To '"' + (gcFileName) + '"'
		*Copy File 'a.tmp' To (gcFileName)

I will report back after 1.6 million test subjects...

Thanks,
Stanley
 
COPY FILE and DELETE FILE are ure VFP commands, RUN and its synonym ! are the only VFP commands, that forward the real command elsewhere.

Can you give a bigger scope? What is the IF condition? IF FILE()? Are you aware it can give false positives, if the file is included in the EXE? or if it is found along PATH? As far as I understand you have a prolem with COPY TO creating the gcFileName. Copy File can't overwrite files that are open. Your problem most probably is an open file, not the mere existance or its readonly flag. Open files can't be overwritten, no matter if your elevaed, admin, network admin or Bill Gates.

What's the bigger picture? If you need to process a batch of files, do you copy each into a single place/falename? Why? You'r introducing a bottleneck not needed at all. But before I expand on the why and how, what are you trying to accomplish?

Bye, Olaf.

 

Dave,
>> Have all the sub-directories been created prior to writing the files?
Yes

Jack,
Thanks you for the nugget that run cannot be trusted.

I just 1 hour ago got this thing working without errors and without any builtin delays with inkey().

While researching what Olaf mentioned, it turns out the file was in use by vfp9 as per the OS's dialog when trying to delete it. Once the dialog is closed, the file was still open, which is what I'd expect. Try to delete it again, and we get the same "cannot delete, file in use by vfp" dialog, again expected. Then close it and double click the file and it opens right up, not what I expected. If it is opened by vfp as the delete dialog claims, why should I be able to open and view the file?

Anyway, because the only way I could find or think of was fclose(x) in a do while loop from 1 to 99 as I did not know the file handle. That worked and the whole dowhile costed about 2ms. Any other way, caused the "cannot create file" error, unless I slowed it down by inserting an inkey(xx) command, and that was too slow.

Right now it is speeding along and up to 125,400 without the first message as in encrypts the files and resets readonly attribute if they were originally set to +R...

Thanks to all who helped,
Stanley
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top