I have a Delphi app that regularly writes to a local disk file. Occasionally it is unable to access the file – a sharing violation results when it tries to open it. A retry after a short delay is all that is needed, but when it occurs, I would like to report the process that prevented the access.
Is it feasible when a sharing violation occurs for my program to enumerate all the file handles in use, inspect the filename, and if it matches the name of my data file, retrieves the process name associated with that handle?
Some example code would be nice.
You have basically two ways
The Easy Way
if you are using Windows Vista or newer try the
IFileIsInUseinterfaceThe Hard Way
if you need a method compatible with Windows XP,Vista,7 and so on. then you use the NtQuerySystemInformation, NtQueryInformationFile and NtQueryObject functions.
These are the steps to proceed
PROCESS_DUP_HANDLErealhandle to the file.Note 1 : the tricky part of this method is resolve the filename based in a handle. the function
NtQueryInformationFilehangs in some scenarios (system handles and others) a workaround to prevent the entire application from hanging is call the function from a separate thread.Note 2 : exist another functions like GetFileInformationByHandleEx and GetFinalPathNameByHandle to resolve the filename of a handle. but both exist since Windows viste an d in such case is better use
IFileIsInUse.Check this sample application tested in Delphi 2007, XE2 and Windows XP and 7. from here you can take some ideas to resolve your issue.
Note : The function
GetProcessIdUsingFileOnly compares the name of the files (not the path).