Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
479 views
in Technique[技术] by (71.8m points)

windows - How to check if a file is already open by another process in C?

I see that standard C has no way of telling if a file is already opened in another process. So the answer should contain several examples for each platform. I need that check for Visual C++ / Windows though.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Windows: Try to open the file in exclusive mode. If it works, no one else has opened the file and will not be able to open the file

HANDLE fh;
fh = CreateFile(filename, GENERIC_READ, 0 /* no sharing! exclusive */, NULL, OPEN_EXISTING, 0, NULL);
if ((fh != NULL) && (fh != INVALID_HANDLE_VALUE))
{
   // the only open file to filename should be fh.
   // do something
   CloseHandle(fh);
}

MS says: dwShareMode

The sharing mode of an object, which can be read, write, both, delete, all of these, or none (refer to the following table).

If this parameter is zero and CreateFile succeeds, the object cannot be shared and cannot be opened again until the handle is closed.

You cannot request a sharing mode that conflicts with the access mode that is specified in an open request that has an open handle, because that would result in the following sharing violation: ERROR_SHARING_VIOLATION.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx

extension: how to delete a (not readonly) file filesystem which no one has open for read/write?

access right FILE_READ_ATTRIBUTES, not DELETE. DELETE could cause problems on smb share (to MS Windows Servers) - CreateFile will leave with a still open FileHandle /Device/Mup:xxx filename - why ever and whatever this Mup is. Will not happen with access right FILE_READ_ATTRIBUTES use FILE_FLAG_OPEN_REPARSE_POINT to delete filename. Else you will delete the target of a symbolic link - which is usually not what you want

HANDLE fh;
fh = CreateFile(filename,  FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE /* no RW sharing! */, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_DELETE_ON_CLOSE, NULL);
if ((fh != NULL) && (fh != INVALID_HANDLE_VALUE))
{
    DeleteFile(filename); /* looks stupid?
                          * but FILE_FLAG_DELETE_ON_CLOSE will not work on some smb shares (e.g. samba)!
                          * FILE_SHARE_DELETE should allow this DeleteFile() and so the problem could be solved by additional DeleteFile()
                          */
    CloseHandle(fh); /* a file, which no one has currently opened for RW is delete NOW */

} 

what to do with an open file? If the file is open and you are allowed to do an unlink, you will be left a file where subsequent opens will lead to ACCESS_DENIED. If you have a temporary folder, then it could be a good idea to rename(filename, tempdir/filename.delete) and delete tempdir/filename.delete.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...