Microsoft KB Archive/817805

= PRB: Data Loss in Visual FoxPro Data Files After Abnormal Shutdown =

Article ID: 817805

Article Last Modified on 4/10/2003

-

APPLIES TO


 * Microsoft Visual FoxPro 6.0 Professional Edition

-



SYMPTOMS
After a computer that hosts Visual FoxPro data files stops responding, or in any way is not shut down correctly, data that has been previously written to this file from Visual FoxPro 6.0 may be lost.



CAUSE
The behavior may occur when the temporary attribute of a data file is set to ON. Visual FoxPro sets the temporary attribute of a data file to ON when you issue any of the following commands: PACK [MEMO] ALTER TABLE MODIFY STRUCTURE



STATUS
This problem does not occur in Microsoft Visual FoxPro 7.0, or in Microsoft Visual FoxPro 8.0.



Steps to Reproduce the Behavior
The following code creates three Visual FoxPro tables, inserts data in the tables, and manipulates the tables with PACK, ALTER TABLE and MODIFY STRUCTURE commands. The code also checks for the temporary attribute on the data files. If the data files have the temporary attribute set, the code removes the attribute.  Start Visual FoxPro 6.0. On the File menu, click New. In the New dialog box, click Program, and then click New File.  Paste the following the code in the new program: CLEAR CLOSE DATA ALL curpath = JUSTPATH(SYS(16)) CD (curpath) LOCAL a, i, j = SYS(3050, 1, 256000) = SYS(3050, 2, 256000) ERASE DATA*.*

FOR i = 1 TO 3 WAIT WINDOW [Creating Tables...] NOWAIT NOCLEAR CREATE TABLE (&quot;DATA&quot; + TRANSFORM(i)) ; (DATA1 C(100), DATA2 C(100), DATA3 C(100), ;                data4 C(100),num1 numeric(6),mmemo m) ENDFOR

a = REPLICATE(&quot;a&quot;,100) FOR j = 1 TO 3 FOR i = 1 TO 90000 WAIT WINDOW [Populating Table DATA] + TRANSFORM(j) + ; [. Adding record ] + TRANSFORM(i) + [ of 90000. Please wait...] NOWAIT INSERT INTO (&quot;DATA&quot; + TRANSFORM(j)) VALUES (a,a,a,a,i,REPLICATE(a,10)) ENDFOR ENDFOR WAIT CLEAR

SELECT DATA1 GO TOP DELETE NEXT 10 PACK PACK MEMO ALTER TABLE DATA2 DROP COLUMN DATA1 SELECT DATA3 MESSAGEBOX([Please remove a field from the following dialog, then close it.], 0, []) MODIFY STRUCTURE

=CheckAptt

PROCEDURE CheckAptt EXTERNAL ARRAY lpaDataFilesArray #DEFINE FILE_ATTRIBUTE_READONLY   1 #DEFINE FILE_ATTRIBUTE_HIDDEN       2 #DEFINE FILE_ATTRIBUTE_SYSTEM       4 #DEFINE FILE_ATTRIBUTE_ARCHIVE     32 #DEFINE FILE_ATTRIBUTE_NORMAL      128 #DEFINE FILE_ATTRIBUTE_TEMPORARY 256 #DEFINE CRLF CHR(13) + CHR(10)

DECLARE INTEGER GetFileAttributes IN Win32API STRING FileName DECLARE INTEGER SetFileAttributes IN Win32API STRING FileName, ; INTEGER Attribs

LOCAL laDataFilesArray[1], ; lnFileCount

PUBLIC gcDir, gcOutput

gcDir = [] lnFileCount = 0 gcOutput = []

gcDir = curpath

gcOutput = [**] + CRLF + ; [OUTPUT FOR ] + gcDir

CD (gcDir) lnFileCount = ADIR(laDataFilesArray, [*.D??],[SH])     && Do .DBF, .DBC, .DCX, .DCT first Check_and_Adjust_Files(lnFileCount, @laDataFilesArray, [*.DB*])

lnFileCount = ADIR(laDataFilesArray, [*.FPT],[SH])     && Do general/memo files Check_and_Adjust_Files(lnFileCount, @laDataFilesArray, [*.FPT])

lnFileCount = ADIR(laDataFilesArray, [*.?DX],[SH])     && IDX/CDX Index files Check_and_Adjust_Files(lnFileCount, @laDataFilesArray, [*.*DX])

gcOutput = gcOutput + [**] + CRLF + CRLF

STRTOFILE(gcOutput, [OUTPUT.TXT], .F.)

CLEAR DLLS MODI FILE OUTPUT.txt RETURN ENDPROC

PROCEDURE Check_and_Adjust_Files(lpnFileCount, lpaDataFilesArray, lpcFileSkeleton) IF lpnFileCount = 0 gcOutput = gcOutput + CRLF + ; [  No files of type ] + lpcFileSkeleton + [ found.] + CRLF ENDIF

LOCAL i        FOR i = 1 TO ALEN(lpaDataFilesArray, 1) gcOutput = gcOutput + CRLF + [  ] + ; GetFAttr(ADDBS(gcDir) + lpaDataFilesArray(i,1)) ENDFOR

gcOutput = gcOutput + CRLF RETURN ENDPROC

PROCEDURE GetFAttr(lpcFileName) LOCAL lvAttribute, lcRetVal, lcResetStr, llAdjusted

lvAttribute = GetFileAttributes(lpcFileName)

lcRetVal = [] lcResetStr = [] llAdjusted = .F.

IF BITAND(lvAttribute, FILE_ATTRIBUTE_READONLY) = ; FILE_ATTRIBUTE_READONLY lcRetVal = lcRetVal + 'Read only  ' lcResetStr = lcResetStr + [FILE_ATTRIBUTE_READONLY,] ENDIF

IF BITAND(lvAttribute, FILE_ATTRIBUTE_HIDDEN) = FILE_ATTRIBUTE_HIDDEN lcRetVal = lcRetVal + 'Hidden  ' lcResetStr = lcResetStr + [FILE_ATTRIBUTE_HIDDEN,] ENDIF

IF BITAND(lvAttribute, FILE_ATTRIBUTE_SYSTEM) = FILE_ATTRIBUTE_SYSTEM lcRetVal = lcRetVal + 'System  ' lcResetStr = lcResetStr + [FILE_ATTRIBUTE_SYSTEM,] ENDIF

IF BITAND(lvAttribute, FILE_ATTRIBUTE_ARCHIVE) = FILE_ATTRIBUTE_ARCHIVE lcRetVal = lcRetVal + 'Archive  ' lcResetStr = lcResetStr + [FILE_ATTRIBUTE_ARCHIVE,] ENDIF

IF BITAND(lvAttribute, FILE_ATTRIBUTE_NORMAL) = FILE_ATTRIBUTE_NORMAL lcRetVal = lcRetVal + 'Normal  ' lcResetStr = lcResetStr + [FILE_ATTRIBUTE_NORMAL,] ENDIF

IF BITAND(lvAttribute, FILE_ATTRIBUTE_TEMPORARY) = FILE_ATTRIBUTE_TEMPORARY lcRetVal = lcRetVal + 'Temporary  ' lcResetStr = lcResetStr + [FILE_ATTRIBUTE_TEMPORARY,] ENDIF

lcResetStr = LEFT(lcResetStr,LEN(lcResetStr)-1) IF [FILE_ATTRIBUTE_TEMPORARY] $ lcResetStr RemoveTemp(lpcFileName,lcResetStr) llAdjusted = .T.        ENDIF

RETURN [File ] + JUSTFNAME(lpcFileName) + [: ] + lcRetVal + ; IIF(llAdjusted, [ (TEMP ATTRIBUTE REMOVED!)], []) ENDPROC



PROCEDURE RemoveTemp(lpcFileName, lcSetStr) IF lcSetStr = [FILE_ATTRIBUTE_TEMPORARY] lcSetStr = [FILE_ATTRIBUTE_NORMAL] ENDIF

lcSetStr = STRTRAN(lcSetStr, [,FILE_ATTRIBUTE_TEMPORARY], []) IF ([,] $ lcSetStr) && More than one attribute SetFileAttributes(lpcFileName, BITOR(&lcSetStr)) ELSE SetFileAttributes(lpcFileName, &lcSetStr) ENDIF RETURN ENDPROC  In a new, empty directory, save the program as TEMPTEST.prg . Run the program, and then follow the prompts.</li></ol>

When the execution of the program completes, you see a text file that lists the Visual FoxPro files for which the temporary attribute was set.

Keywords: kbprb kbcode KB817805

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.