In thread 184-1674267 the poster asked how to tell if a file was open. After a bit of prompting he/she explained that it was an Excel file that was "open, meaning visible in your taskbar".
Mike Lewis offered a solution using APIs, GriffMG offered a solution using low level file calls and there was other advice.
I don't know what I'm doing wrong but the low level file calls don't work for me as hopefully is clear from the following:
With the VFP IDE open, use file explorer (or whatever) to open, say "C:\MyFolder\MyFile.txt", a file with some text in it.
Return to the VFP IDE and enter the following (and get the following results)
public gnHandle
public gnBytes
m.gnHandle = FOPEN("C:\MyFolder\MyFile.txt", 12)
?m.gnHandle && 21 (For example)
m.gnBytes = FWRITE(m.gnHandle, "This is the house")
?m.gnBytes && 17
?FCLOSE(m.gnHandle) && .T.
Switch to the open file "C:\MyFolder\MyFile.txt" - there is no change.
Either: close the file without editing it, open it again and there is the "This is the house"
or: edit the file, close and save and then reopen it and there is no "This is the house"
I don't understand why what I get seems to be so much at variance with the advice given, especially from Olaf Doschke, a man with whom I would be very afraid to start an argument. From what I read, I expected the FOPEN() funtion to return -1 if the file "C:\MyFolder\MyFile.txt" was open in another application
Mike Lewis's API solution worked for me, but I also need to know the path name for the file. My knowledge of API usage is very limited, I use them strictly on a "monkey see, monkey do" basis.
However I found 3 possibilities, GetFinalPathNameByHandle, GetFinalPathNameByHandleA and GetFinalPathNameByHandleW. No idea what the difference is. I tried them inside Mike's code. My declaration for all of them was
DECLARE integer GetFinalPathNameByHandle IN WIN32API ;
integer hFile, string lpszFilePath, integer cchFilePath, ;
integer dwFlags
Same for the ...A and the ...W
My usage was
lcBuffer = REPLICATE(CHR(0), 250)
GetFinalPathNameByHandle(hNext, lcBuffer, LEN(lcBuffer), 0x8)
Same for the ...A or ...W. hNext is the handle returned for the file in Mike's code.
This failed. I managed to paste in GetLastError() code from an ancient VFP knowledgebase article. This told me the error was 6 "The handle is invalid"
Could someone please tell me (1) what I'm doing wrong with the low level functions, (2) what I'm doing wrong with the API functions and (3) How to find out if a non VFP file is open in a non VFP application, and if so its path.
If I haven't yet bored you all to death, the practicalities of my question are as follows: My (tiny) application frequently writes to a file named user.log as a means of maintaining an audit trail. The user can view and edit the log from a shellexecute in the application menu. I want to cover the situation where the user (or for that matter anybody else with access to the folder) may have opened the log and perhaps forgotten about it. I want to be sure it is closed in any other application before it is written to by mine. If it is open, perhaps being edited because it has become to big, then tough, out it goes. If there is another application with a user.log and it is open, I want to leave that one alone.
Thanks for your patience
Mike Lewis offered a solution using APIs, GriffMG offered a solution using low level file calls and there was other advice.
I don't know what I'm doing wrong but the low level file calls don't work for me as hopefully is clear from the following:
With the VFP IDE open, use file explorer (or whatever) to open, say "C:\MyFolder\MyFile.txt", a file with some text in it.
Return to the VFP IDE and enter the following (and get the following results)
public gnHandle
public gnBytes
m.gnHandle = FOPEN("C:\MyFolder\MyFile.txt", 12)
?m.gnHandle && 21 (For example)
m.gnBytes = FWRITE(m.gnHandle, "This is the house")
?m.gnBytes && 17
?FCLOSE(m.gnHandle) && .T.
Switch to the open file "C:\MyFolder\MyFile.txt" - there is no change.
Either: close the file without editing it, open it again and there is the "This is the house"
or: edit the file, close and save and then reopen it and there is no "This is the house"
I don't understand why what I get seems to be so much at variance with the advice given, especially from Olaf Doschke, a man with whom I would be very afraid to start an argument. From what I read, I expected the FOPEN() funtion to return -1 if the file "C:\MyFolder\MyFile.txt" was open in another application
Mike Lewis's API solution worked for me, but I also need to know the path name for the file. My knowledge of API usage is very limited, I use them strictly on a "monkey see, monkey do" basis.
However I found 3 possibilities, GetFinalPathNameByHandle, GetFinalPathNameByHandleA and GetFinalPathNameByHandleW. No idea what the difference is. I tried them inside Mike's code. My declaration for all of them was
DECLARE integer GetFinalPathNameByHandle IN WIN32API ;
integer hFile, string lpszFilePath, integer cchFilePath, ;
integer dwFlags
Same for the ...A and the ...W
My usage was
lcBuffer = REPLICATE(CHR(0), 250)
GetFinalPathNameByHandle(hNext, lcBuffer, LEN(lcBuffer), 0x8)
Same for the ...A or ...W. hNext is the handle returned for the file in Mike's code.
This failed. I managed to paste in GetLastError() code from an ancient VFP knowledgebase article. This told me the error was 6 "The handle is invalid"
Could someone please tell me (1) what I'm doing wrong with the low level functions, (2) what I'm doing wrong with the API functions and (3) How to find out if a non VFP file is open in a non VFP application, and if so its path.
If I haven't yet bored you all to death, the practicalities of my question are as follows: My (tiny) application frequently writes to a file named user.log as a means of maintaining an audit trail. The user can view and edit the log from a shellexecute in the application menu. I want to cover the situation where the user (or for that matter anybody else with access to the folder) may have opened the log and perhaps forgotten about it. I want to be sure it is closed in any other application before it is written to by mine. If it is open, perhaps being edited because it has become to big, then tough, out it goes. If there is another application with a user.log and it is open, I want to leave that one alone.
Thanks for your patience