Hi Olaf,
>> What is really causing the 1102 error? Do you have an error handler showing you the line number LINENO()?
The error is occuring when writing gcFileName. Here is the latest version that does not blindly close files like I wanted. It involves a custom handler that issues a retry when that error is raised.
Code:
Procedure FileEncrypt
lnSuccess = goCrypt.CkEncryptFile(Alltrim(gcFileName), 'enc.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
llRetry = .T.
llResetReadOnly = .T.
Else
Delete File (gcFileName)
Exit
Endif
Enddo
lcOutFile = Strtofile(Filetostr('enc.tmp') + lcKey1, 'z.tmp', 0)
*lcOutFile = Strtofile(Filetostr('enc.tmp') + lcKey1, (gcFileName), 0)
*lcOutFile = Strtofile(Filetostr('a.tmp') + lcKey1, (gcFileName), 0)
Store 'Copy File "z.tmp" To ' + '"' + (gcFileName) + '"' To zCommand
&zCommand
If llResetReadOnly = .T.
Store "Attrib +r " + '"' + (gcFileName) + '"' To cCommand
Run /N2 &cCommand
Endif
Delete File '*.tmp'
Endif
Endproc
Here is the error handler...
Code:
Procedure ErrorAction
Parameter llShowDetail, gcFileName, merror, Mess, mess1, mprog, mlineno
If llShowDetail
? gcFileName
? 'Number: ' + Ltrim(Str(merror))
? 'Message: ' + Mess
? 'Line of code with error: ' + mess1
? 'Line number of error: ' + Ltrim(Str(mlineno))
Endif
Inkey(.05)
Retry
Endproc
And here is the the on error call...
Code:
llShowDetail = .F.
Do While !Eof('FileList')
Y=Y+1
r=r+1
On Error Do ErrorAction With llShowDetail, gcFileName, ;
Error(), Message(), Message(1), Program(), Lineno()
>> also FileList.full_path might have same names in sequential records.
No, all full+path values are unique...
>> lcOutfile = SRTRTOFILE() makes no sense at all from the variable naming, lcOutfile will not contain the output file
True, it only contains as you said, the number of bytes written... In tracking this down I did test lcOutfile for a value greater than 0, just to make sure that SRTRTOFILE() created a non zero length file. All files created had a >0 file size, so that wasn't the problem.
>> nae expressions... no need for neither name expresion nor macrosubstitution in functions, nae expressions are only needed in commands.
I know that your nae above is a typo, not sure what you meant?
>> so the problem is the OS level not closing the output file of STRTOFILE() before you do the next processing of it, isn't it?
Yes, a previous file operation on gcFileName doesn'g get finished in time, before the next file operation...
Just thinking out loud now, would a begin/end transaction force filesystem I/O? Or is it just a table and record framework?
Code:
lcOutFile = Strtofile(Filetostr('a.tmp') + lcKey1, (gcFileName), 0)
Do CloseFile
I've tried multiple iteration using multiple file names and all with the same error, as the problem occurs when writing it back to the original filename as defined in gcFileName which get populated by full_path. I don't have a choice here if I want it to go back to the original location and use its original filename.
I even tried your version, that failed... It failed, not because of the .tmp files, but the writing of the final file.
Code:
lcSourceFile = "org"+SYS(2015)+".tmp"
lcSourceFile = ''
lcOutFile = Strtofile(Filetostr('a.tmp') + lcKey1, (lcSourceFile), 0)
Store 'Copy File ' + (lcSourceFile) + ' To ' + '"' + (gcFileName) + '"' To zCommand
&zCommand
also tried...
copy file (lcSourceFile) to (gcFileName)
and
copy file lcSourceFile to gcFileName
This is what I'm using now...
lcOutFile = Strtofile(Filetostr('a.tmp') + lcKey1, 'z.tmp', 0)
Store 'Copy File "z.tmp" To ' + '"' + (gcFileName) + '"' To zCommand
&zCommand
>> avoiding to use any file name twice, you still make any processing go through a.tmp, why?
Let me explain... The process of encrypting a file goes as follows,
1. I copy FileList.full_path to gcFileName,
2. Once the file is internally checked to determine that it is not already encrypted, I pass gcFileName to the encryption function as input and after encrypting the file the function outputs the file the 'enc.tmp'
3. Now the strtofile(filetostr... takes 'enc.tmp' file as input and appends the value of lcKey1, then outputs a new file 'z.tmp' that contains the "original file as encrypted" with the "appended key as NOT encrypted". It is this key that step 2 uses to determine if the file is encrypted.
4. Delete gcFileName,
5. Finally copy 'z.tmp' to its original location and name as contained in gcFileName,
6. Do it all again...
Given the steps involved, I don't how to make it work without using z.tmp multiple times. Best I can see, it doesn't matter as that is not where the problem is.
Thanks,
Stanley