PsUtil Notes

Page Contents

Find Out Which Process Has Locked A File

PsUtil is ...a cross-platform library for retrieving information on running processes and system utilization....

I wanted to know how to find out if a file was alread open in Excel as I thought it would be nice to give an informative error message to my application's user if the file was locked whilst the app was trying to write it.

Found the answer in this SO thread and the code below is basically just a copy of the answer with a couple of adjustments. I found to compare the file names correctly I had to use os.path.normcase() (on Windows at least) and I had to change get_open_files() to open_files(). Also added an extra exception handler to handle access-denied issues.

def IsFileAvailableToWrite(filename):
   filename = os.path.normcase(os.path.abspath(filename))
   for proc in psutil.process_iter():
      try:
         for nt in proc.open_files():
            if os.path.normcase(os.path.abspath(nt.path)) == filename:
               return (proc.pid, proc.name())
      except psutil.NoSuchProcess as e:
         # Catches race condition where a proc ends b4 we can examine its files
         pass
      except psutil.AccessDenied as e:
         # If we're not root/admin sometimes we can't query processes
         pass
   return (None, None)

The to figure out if the write failed I catch the IOError exception as follows:

retry = True
while retry:
   try:
      ## YOUR FILE WRITE HERE ##
      pandas_dataframe_obj.to_csv(myFile, ...)
      retry = False
   except IOError as e:
      if e.errno != errno.EACCES: # Only catch access denied errors
         raise
      else:
         pid, pname = IsMapAvailableToWrite(myFile)
         if pid is not None:
            ## Found the process that has this file open ##
            print "The file is already in use. Owned by '{}'".format(pname)
            result = GetUserInput("Have you closed the program?", "yn")
            if result != UserInput.YES:
               raise
         else:
            raise