Christina Patricia
Christina Patricia

Reputation: 21

How do I close MS Office files after decryption in Python?

I'm writing a function that decrypts encrypted word files. I am using the MSOffCrypto package. I would like the function to decrypt the file if it is encrypted and to create the decrypted file in a new folder. I would like for the program to close the file and delete it. If the file is not encrypted, I would like for the program to move the original file to the same folder as the decrypted files. Here is what I have written so far:

def DecryptFile(listdir):
    #Create a new directory for decrypted report files.
    #Decryption is necessary to scrape embedded documents.
    DecryptReportPath = dir + "\\ParentReportFiles\\"
    os.mkdir(DecryptReportPath)
    #Loop iterates through each file in the selected directory
    for filename in listdir:
        if (filename[-3:] == 'doc') | (filename[-4:] == 'docx'):
            p = Path(filename)
            PathParts = p.parts
            try:
                #Try to decrypt the MSOffice File.
                try:
                    file = msoffcrypto.OfficeFile(open(filename, "rb"))
                    if file.is_encrypted():
                        # Use password
                        file.load_key(password="Viking1234!")
                        #Create the decrypted file in a new folder called ParentReportFiles
                        file.decrypt(open(DecryptReportPath + PathParts[-1][0:-5] + "decrypted.docx", "wb"))
                        file.close()
                        os.remove(filename)
                    else:
                        file.close()
                        os.rename(filename, DecryptReportPath+PathParts[-1])
                except:
                    traceback.print_exc()
                    continue
            except:
                print("File is not doc")

The problem is that I get the following error message:

Traceback (most recent call last):
  File "C:/Users/.../Filing Master File 16 Dec 20.py", line 37, in DecryptFile
    file.close()
AttributeError: 'OOXMLFile' object has no attribute 'close'

Without the file.close() line, I get the following error:

Traceback (most recent call last):
  File "C:/Users/.../Filing Master File 16 Dec 20.py", line 38, in DecryptFile
    os.remove(filename)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\...\\myfile.docx'

I've tried to substitute file.close() with os.close(file), but it doesn't work either:

Traceback (most recent call last):
  File "C:/Users/.../Filing Master File 16 Dec 20.py", line 37, in DecryptFile
    os.close(file)
TypeError: an integer is required (got type OOXMLFile)

Please advise, thank you very much!

Upvotes: 0

Views: 861

Answers (1)

running.t
running.t

Reputation: 5709

I guess the problem is here

  file = msoffcrypto.OfficeFile(open(filename, "rb"))

msoffcrypto.OfficeFile does not return a file-like object which implements close() method, but object of type OOXMLFile Most probably what you wanted to close was result of open(filename, "rb") operation. So what I would try is

 org_file = open(filename, "rb")
 file = msoffcrypti.OfficeFile(org_file)
 ...
 org_file.close()

Please also take a note that you can use open operation as a contex manager and simply don't care explicit closing files. It would be:

 with open(filename, "rb") as org_file:
     file = msoffcrypti.OfficeFile(org_file)
     ...
 os.remove(filename)

Upvotes: 2

Related Questions