I have an application that writes files to a folder, I want to prevent (or at least show a warning) if another instance of my application attempts to write to the same directory.
Is there a way I can temporarily block access to a folder to prevent this from happening?
EDIT:
I had an idea about creating a temp file to use as a flag, however is there a way to ensure that a temp file is deleted if my application were to crash?
Why not use a lock file?
You have to ensure, that the "check-and-create" operation is atomic. If it tells You that the lockfile already exists, then there is another process accessing the directory.
Blocking the whole directory for other processes is not what You want. You would also block shells and files browsers from accessing it.
I saw Your edit: You could write the process ID of the file into the lockfile.
If Your application detects an existing lock file, it can check if a process with that ID exists. If it doesn't, remove the lockfile and start over.
Related
Is it safe enough to store a file in the %TEMP% directory via GetTempPath, GetTempPath and CreateFile for more than two hours? Is there any guarantees that this file won't be deleted earlier?
Thanks in advance.
A file you create in the TEMP directory must be created with the CreateFile's FILE_FLAG_DELETE_ON_CLOSE option. This ensures that the file will always be cleaned-up and you cannot spray garbage files, even if your program crashes before it has a chance to delete the file again.
This option then also inevitably forces you to do the Right Thing, keeping the file opened while you are using it. Which in turn prevents anybody from the deleting the file, even if they use a sledge-hammer.
Lots of programs don't follow this advice and a user's TEMP directory tends to be a big olde mess, forcing the user to clean it up manually once in a while. A built-in feature of Windows, he'll use the "Disk Cleanup" applet. The kind of scenario where you will lose the file if you don't follow this advice. Best to use %AppData% instead.
There are no guarantees. This folder is usually not cleared except the user starts any cleanup.
But everyone can delete files here. And it is wise to do that on a regular base
To prevent the file from being deleted, you can keep a handle open (assuming the application is running the whole time) and do not specify FILE_SHARE_DELETE (and, if applicable, neither FILE_SHARE_WRITE).
Alternative:
Use a path in %APPDATA% or %PROGRAMDATA% that you clear yourself regulary, or let the user specify a path.
In addition, you could register a scheduled task to clean the folder regulary.
If you do not want that another process can delete your files, just keep them open with a share mode of FILE_SHARE_READ | FILE_SHARE_WRITE. That way any attempt to delete them will fail, but any other process will be able to read or write them.
BTW : this is not related with the files living in %TEMP% folder.
If you cannot have a process to keep them open all the time, you must rely on other processes (and other users) on your system not doing anything ...
I have the following scenario:
I can create an object with some arguments and it will load asynchronously (using boost::thread) one directory, which will have many subdirectories and there are many many files, and save to specific directory on disk. The files can be loaded from web or anything else and it can take some minutes to finish the job.
Just after creating the object user may want to load one specific file. Right now I am checking if the file exists (meaning the thread has alread downloaded it), otherwise I can call thread.join() to ensure all files are loaded or check the file existence every 100 ms or sth like that. But is there a way to do it better, meaning the thread that is doing his job will inform me when the wanted file is loaded, using some callback or sth like that?
As you said, you can use a callback, for example you could have a set of observed files in the thread, and for every file downloaded you search in the set, and if the file you just donwloaded is there, you fire the callback, possibly in another thread so the thread will continue its job. Try to use a set to the find wil be faster, for example faster then searching in a vector.
I suggest you to use a concurrent container (native implementation in MS VC++, linux alternative: Intel TBB) and just add downloaded files to it :) then you can issue a .find or anything else.
This way you don't have to worry about locks and other threat safety stuff.
Use boost::condition variable http://www.boost.org/doc/libs/1_53_0/doc/html/thread/synchronization.html
Add 2 variables, one boolean flag and one string with filePath.
When thread which is opening the file finds that there is file which it is looking for, set flag on true, and filePath. Wait for the flag to be changed on condition variable
Thread which is loading files in background everytime it loads file it checks the flag and filePath, if the flag is set on true and the file it loaded is as expected notify the thread.
I have an application suite that I maintain for Windows platforms. I recently added some code to a shared library to remove a directory after the app is done with it. In one app, the deletion is successful; in the other, I receive a message telling me the file is in use by another process.
After downloading Process Explorer, I learned what I had already expected, that the process holding the folder is the one trying to delete it.
When I google for an answer, all I see is, "You need to download XYZ to find out what process is holding the file, then close that process," where "XYZ" is Unlocker, Process Explorer, etc. I know the process that is holding the file, but if I terminate it, how can it delete the folder?
Does anyone have any idea about how to locate the code that is holding the folder open? Of the tools that are available for finding which processes are using which files, can any be used to find where in the process the folder is open?
There is no concept of a "location in the process" where a file is open. E.g. a very common cause of unintentional open files are leaked handles. That means the file is open precisely because there is no location for the file handle in the process anymore.
I included a exe file as a resource in my c++ application and i need to run it, but i need to restrict it's access alot so the user can't copy it.
I need to keep it's handle opened so external programs can't access it, and because i used FILE_FLAG_DELETE_ON_CLOSE as a flag, so it will delete if my application gets killed.
But because of that i can't run it with CreateProcess() or WinExec().
I know it sounds weird, but i have a good reason.I need those to protect the executable of a game from a dll-injection cheat, and i don't have the code of that exe.
Since you can't lock the entire file, lock a very small part with LockFile. You'll need to find a byte range that Windows doesn't use. You might achieve this by adding a dummy resource to the EXE. (This does not require source code).
How can I check if a file is still being written? I need to wait for a file to be created, written and closed again by another process, so I can go on and open it again in my process.
In general, this is a difficult problem to solve. You can ask whether a file is open, under certain circumstances; however, if the other process is a script, it might well open and close the file multiple times. I would strongly recommend you use an advisory lock, or some other explicit method for the other process to communicate when it's done with the file.
That said, if that's not an option, there is another way. If you look in the /proc/<pid>/fd directories, where <pid> is the numeric process ID of some running process, you'll see a bunch of symlinks to the files that process has open. The permissions on the symlink reflect the mode the file was opened for - write permission means it was opened for write mode.
So, if you want to know if a file is open, just scan over every process's /proc entry, and every file descriptor in it, looking for a writable symlink to your file. If you know the PID of the other process, you can directly look at its proc entry, as well.
This has some major downsides, of course. First, you can only see open files for your own processes, unless you're root. It's also relatively slow, and only works on Linux. And again, if the other process opens and closes the file several times, you're stuck - you might end up seeing it during the closed period, and there's no easy way of knowing if it'll open it again.
You could let the writing process write a sentinel file (say "sentinel.ok") after it is finished writing the data file your reading process is interested in. In the reading process you can check for the existence of the sentinel before reading the data file, to ensure that the data file is completely written.
#blu3bird's idea of using a sentinel file isn't bad, but it requires modifying the program that's writing the file.
Here's another possibility that also requires modifying the writer, but it may be more robust:
Write to a temporary file, say "foo.dat.part". When writing is complete, rename "foo.dat.part" to "foo.dat". That way a reader either won't see "foo.dat" at all, or will see a complete version of it.
You can try using inotify
http://en.wikipedia.org/wiki/Inotify
If you know that the file will be opened once, written and then closed, it would be possible for your app to wait for the IN_CLOSE_WRITE event.
However if the behaviour of the other application doing the writing of the file is more like open,write,close,open,write,close....then you'll need some other mechanism of determining when the other app has truly finished with the file.