How to check if a file is being used by another application?
You need to use GetLastError()
to know why CreateFile()
failed, eg:
// this is requesting exclusive access to the file, so it will
// fail if the file is already open for any reason. That condition
// is detected by a sharing violation error due to conflicting
// sharing rights...
HANDLE fh = CreateFile("D:\\1.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (fh == INVALID_HANDLE_VALUE)
{
switch (GetLastError())
{
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND:
MessageBox(NULL, "The file does not exist", "Error", 0);
break;
case ERROR_SHARING_VIOLATION:
MessageBox(NULL, "The file is in use", "Error", 0);
break;
//...
default:
MessageBox(NULL, "Error opening the file", "Error", 0);
break;
}
}
else
{
// the file exists and was not in use.
// don't forget to close the handle...
CloseHandle(fh);
}
How can I check if a file is being used by other application?
Without any additional gems, a slightly wasteful way might be:
if %x[lsof -F n].split("\n").grep(/yourfilename/).empty?
# all clear
else
end
Or
if system %Q[lsof #{filename}]
# still open..
else
# all clear
end
Or, ignore my hacked suggestion and use a gem for this: https://github.com/jordansissel/fosl
Python - How to check if a file is used by another application?
Will your python script desire to open the file for writing or for reading? Is the legacy application opening and closing the file between writes, or does it keep it open?
It is extremely important that we understand what the legacy application is doing, and what your python script is attempting to achieve.
This area of functionality is highly OS-dependent, and the fact that you have no control over the legacy application only makes things harder unfortunately. Whether there is a pythonic or non-pythonic way of doing this will probably be the least of your concerns - the hard question will be whether what you are trying to achieve will be possible at all.
UPDATE
OK, so knowing (from your comment) that:
the legacy application is opening and
closing the file every X minutes, but
I do not want to assume that at t =
t_0 + n*X + eps it already closed
the file.
then the problem's parameters are changed. It can actually be done in an OS-independent way given a few assumptions, or as a combination of OS-dependent and OS-independent techniques. :)
- OS-independent way: if it is safe to assume that the legacy application keeps the file open for at most some known quantity of time, say
T
seconds (e.g. opens the file, performs one write, then closes the file), and re-opens it more or less everyX
seconds, whereX
is larger than 2*T
.stat
the file- subtract file's modification time from
now()
, yieldingD
- if
T
<=D
<X
then open the file and do what you need with it - This may be safe enough for your application. Safety increases as
T
/X
decreases. On *nix you may have to double check/etc/ntpd.conf
for proper time-stepping vs. slew configuration (see tinker). For Windows see MSDN
- Windows: in addition (or in-lieu) of the OS-independent method above, you may attempt to use either:
- sharing (locking): this assumes that the legacy program also opens the file in shared mode (usually the default in Windows apps); moreover, if your application acquires the lock just as the legacy application is attempting the same (race condition), the legacy application will fail.
- this is extremely intrusive and error prone. Unless both the new application and the legacy application need synchronized access for writing to the same file and you are willing to handle the possibility of the legacy application being denied opening of the file, do not use this method.
- attempting to find out what files are open in the legacy application, using the same techniques as ProcessExplorer (the equivalent of *nix's
lsof
)- you are even more vulnerable to race conditions than the OS-independent technique
- sharing (locking): this assumes that the legacy program also opens the file in shared mode (usually the default in Windows apps); moreover, if your application acquires the lock just as the legacy application is attempting the same (race condition), the legacy application will fail.
- Linux/etc.: in addition (or in-lieu) of the OS-independent method above, you may attempt to use the same technique as
lsof
or, on some systems, simply check which file the symbolic link/proc/<pid>/fd/<fdes>
points to- you are even more vulnerable to race conditions than the OS-independent technique
- it is highly unlikely that the legacy application uses locking, but if it is, locking is not a real option unless the legacy application can handle a locked file gracefully (by blocking, not by failing - and if your own application can guarantee that the file will not remain locked, blocking the legacy application for extender periods of time.)
UPDATE 2
If favouring the "check whether the legacy application has the file open" (intrusive approach prone to race conditions) then you can solve the said race condition by:
- checking whether the legacy application has the file open (a la
lsof
orProcessExplorer
) - suspending the legacy application process
- repeating the check in step 1 to confirm that the legacy application did not open the file between steps 1 and 2; delay and restart at step 1 if so, otherwise proceed to step 4
- doing your business on the file -- ideally simply renaming it for subsequent, independent processing in order to keep the legacy application suspended for a minimal amount of time
- resuming the legacy application process
Effectively detect if a file is being used by an application
Please take a look into this SO question
Here you can check the application by the application name(easier way):
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
Check if a file is not open nor being used by another process
An issue with trying to find out if a file is being used by another process is the possibility of a race condition. You could check a file, decide that it is not in use, then just before you open it another process (or thread) leaps in and grabs it (or even deletes it).
Ok, let's say you decide to live with that possibility and hope it does not occur. To check files in use by other processes is operating system dependant.
On Linux it is fairly easy, just iterate through the PIDs in /proc. Here is a generator that iterates over files in use for a specific PID:
def iterate_fds(pid):
dir = '/proc/'+str(pid)+'/fd'
if not os.access(dir,os.R_OK|os.X_OK): return
for fds in os.listdir(dir):
for fd in fds:
full_name = os.path.join(dir, fd)
try:
file = os.readlink(full_name)
if file == '/dev/null' or \
re.match(r'pipe:\[\d+\]',file) or \
re.match(r'socket:\[\d+\]',file):
file = None
except OSError as err:
if err.errno == 2:
file = None
else:
raise(err)
yield (fd,file)
On Windows it is not quite so straightforward, the APIs are not published. There is a sysinternals tool (handle.exe
) that can be used, but I recommend the PyPi module psutil
, which is portable (i.e., it runs on Linux as well, and probably on other OS):
import psutil
for proc in psutil.process_iter():
try:
# this returns the list of opened files by the current process
flist = proc.open_files()
if flist:
print(proc.pid,proc.name)
for nt in flist:
print("\t",nt.path)
# This catches a race condition where a process ends
# before we can examine its files
except psutil.NoSuchProcess as err:
print("****",err)
Is there a way to check if a file is in use?
Updated NOTE on this solution: Checking with FileAccess.ReadWrite
will fail for Read-Only files so the solution has been modified to check with FileAccess.Read
.
ORIGINAL:
I've used this code for the past several years, and I haven't had any issues with it.
Understand your hesitation about using exceptions, but you can't avoid them all of the time:
protected virtual bool IsFileLocked(FileInfo file)
{
try
{
using(FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
{
stream.Close();
}
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
//file is not locked
return false;
}
File is used by another process. How to know which process?
You can use ProcessExplorer to search for the file:
- http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
Just run that (maybe you need to launch it with administrator rights), hit Ctrl-F
and type in the name of the file which is locked - it will find all open handles which match the given name, and tell you which process it belongs to.
Related Topics
Rails: Specified 'Mysql2' for Database Adapter But the Gem Is Not Loaded
Split the String to Get Only the First 5 Characters
Best Practices for New Rails Deployments on Linux
Cache Resources Exhausted Imagemagick
Installed Ruby Using Apt-Get Install Ruby 2.0.0 Succeeded But Not Using Correct Ruby Version
Rubyinstaller 2.2.1 and Rails - Rake Cannot Load Nokogiri
Passing Multiple Code Blocks as Arguments in Ruby
How to Prompt for a Sudo Password Using Ruby
How to Wait for Process to Finish Using Io.Popen
Can't Install Ruby on Rails with Rvm on Ubuntu 13.04
Popen Getting Pid of Newly Run Process
How to Check If a File Is Being Used by Other Application
How to Distinguish Xlsx and Docx Files from Zip Archives
Error: Mime-Types-Data Requires Ruby Version >= 2.0
Netbeans and Rails Error: Bin/Ruby: No Such File or Directory -- Script/Rails (Loaderror)
Limit Space and Memory Used by Imagemagick
How to Display Ruby on Rails Form Validation Error Messages One At a Time