Vladimir Buzalka
asked on
Cannot delete file in Python, it is used by another process.
Dear Experts,
I have python code to:
1. retrieve stored MSG email from MongoDB and save it to disk
2. open that stored MSG email via outlook
3. read several things from file
4. close that outlook message
5. delete disk from disk
I am receiving error on os.remove(filename) with error message
Traceback (most recent call last):
File "Z:/Dropbox/#Python/PyChar m/ReadMong o.py", line 71, in <module>
os.remove(filename)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'z:\\00000000B229A92B98C6E 7479C47B8A A566FF2C9E 4842C00.ms g'
But I do not know how to release that file.
I believe I am correctly closing outlook mailitem via postovnizprava.close(1) - argument 1 being DISCARD
Can you advice please or give me any idea to work on?
Thanks
Vladimir
Full code is here:
import time
import pymongo
import os
import gridfs
from bson.objectid import ObjectId
import sys
import win32com.client
# tento proptag zjisti charakter prilohy
PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001F"
# tento proptag zjisti message headers
TransportMessageHeadersSch ema = "http://schemas.microsoft.com/mapi/proptag/0x007D001E"
outlookmapi = win32com.client.Dispatch(" Outlook.Ap plication" ).GetNames pace("MAPI ")
myclient = pymongo.MongoClient("mongo db://192.1 68.1.76:27 017/")
print(myclient.list_databa se_names() )
mydb = myclient["db_emailu"]
print(mydb.name)
fs=gridfs.GridFS(mydb)
fsat=gridfs.GridFS(mydb,"a ttachments ")
nalez=mydb["fs.files"].fin d({}).limi t(1)
for s in nalez:
print(s["entryid"])
filename="z:\\"+s["entryid "]+".msg"
soubor=fs.get(s["_id"]).re ad()
newFile=open(filename,"wb" )
newFile.write(soubor)
newFile.close()
postovnizprava=outlookmapi .openshare ditem(file name)
# postovnizprava.display()
for at in postovnizprava.attachments :
print(at.filename,at.prope rtyaccesso r.getprope rty(PR_ATT ACH_CONTEN T_ID)=="")
if at.propertyaccessor.getpro perty(PR_A TTACH_CONT ENT_ID)==" ":
atFileName="z:\\"+at.filen ame
at.saveasfile(atFileName)
atFile=open(atFileName,"rb ")
fsat.put(atFile.read(),fil ename=at.f ilename,en tryid=s["e ntryid"])
atFile.close()
os.remove(atFileName)
InsertDic={}
InsertDic["entryid"]=s["en tryid"]
InsertDic["subject"] = postovnizprava.subject
InsertDic["sendername"] = postovnizprava.sendername
InsertDic["senderemailaddr ess"] = postovnizprava.senderemail address
InsertDic["to"] = postovnizprava.to
InsertDic["cc"] = postovnizprava.cc
InsertDic["bcc"] = postovnizprava.bcc
InsertDic["categories"] = postovnizprava.categories
InsertDic["receivedtime"] = postovnizprava.receivedtim e
InsertDic["sent"] = postovnizprava.sent
InsertDic["senton"] = postovnizprava.senton
InsertDic["bodyformat"] = postovnizprava.bodyformat
InsertDic["body"] = postovnizprava.body
InsertDic["htmlbody"] = postovnizprava.htmlbody
InsertDic["rtfbody"] = bytes(postovnizprava.rtfbo dy)
InsertDic["importance"] = postovnizprava.importance
InsertDic["headers"] = postovnizprava.propertyacc essor.getp roperty(Tr ansportMes sageHeader sSchema)
x=mydb["emails"].insert_on e(InsertDi c)
print(postovnizprava.entry id)
print(filename)
postovnizprava.close(1)
postovnizprava=None
print(type(postovnizprava) )
os.remove(filename)
sys.exit()
I have python code to:
1. retrieve stored MSG email from MongoDB and save it to disk
2. open that stored MSG email via outlook
3. read several things from file
4. close that outlook message
5. delete disk from disk
I am receiving error on os.remove(filename) with error message
Traceback (most recent call last):
File "Z:/Dropbox/#Python/PyChar
os.remove(filename)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'z:\\00000000B229A92B98C6E
But I do not know how to release that file.
I believe I am correctly closing outlook mailitem via postovnizprava.close(1) - argument 1 being DISCARD
Can you advice please or give me any idea to work on?
Thanks
Vladimir
Full code is here:
import time
import pymongo
import os
import gridfs
from bson.objectid import ObjectId
import sys
import win32com.client
# tento proptag zjisti charakter prilohy
PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001F"
# tento proptag zjisti message headers
TransportMessageHeadersSch
outlookmapi = win32com.client.Dispatch("
myclient = pymongo.MongoClient("mongo
print(myclient.list_databa
mydb = myclient["db_emailu"]
print(mydb.name)
fs=gridfs.GridFS(mydb)
fsat=gridfs.GridFS(mydb,"a
nalez=mydb["fs.files"].fin
for s in nalez:
print(s["entryid"])
filename="z:\\"+s["entryid
soubor=fs.get(s["_id"]).re
newFile=open(filename,"wb"
newFile.write(soubor)
newFile.close()
postovnizprava=outlookmapi
# postovnizprava.display()
for at in postovnizprava.attachments
print(at.filename,at.prope
if at.propertyaccessor.getpro
atFileName="z:\\"+at.filen
at.saveasfile(atFileName)
atFile=open(atFileName,"rb
fsat.put(atFile.read(),fil
atFile.close()
os.remove(atFileName)
InsertDic={}
InsertDic["entryid"]=s["en
InsertDic["subject"] = postovnizprava.subject
InsertDic["sendername"] = postovnizprava.sendername
InsertDic["senderemailaddr
InsertDic["to"] = postovnizprava.to
InsertDic["cc"] = postovnizprava.cc
InsertDic["bcc"] = postovnizprava.bcc
InsertDic["categories"] = postovnizprava.categories
InsertDic["receivedtime"] = postovnizprava.receivedtim
InsertDic["sent"] = postovnizprava.sent
InsertDic["senton"] = postovnizprava.senton
InsertDic["bodyformat"] = postovnizprava.bodyformat
InsertDic["body"] = postovnizprava.body
InsertDic["htmlbody"] = postovnizprava.htmlbody
InsertDic["rtfbody"] = bytes(postovnizprava.rtfbo
InsertDic["importance"] = postovnizprava.importance
InsertDic["headers"] = postovnizprava.propertyacc
x=mydb["emails"].insert_on
print(postovnizprava.entry
print(filename)
postovnizprava.close(1)
postovnizprava=None
print(type(postovnizprava)
os.remove(filename)
sys.exit()
ASKER
Dear Ste5an
it does not work, I added time.sleep(20) and error is the same. But when script finishes with error, and I switch to file explorer, I can simply delete file, it is not kept by any process anymore.
Advice?
Many thanks
Vladimir
it does not work, I added time.sleep(20) and error is the same. But when script finishes with error, and I switch to file explorer, I can simply delete file, it is not kept by any process anymore.
Advice?
Many thanks
Vladimir
Maybe a mail message parser is a better solution then start out of control other processes to read part from a message:
https://pypi.org/project/eml-parser/
https://pypi.org/project/EmailParser/
Basically msg file are just text files. (should be..., as all data is supposed to be ascii).
https://pypi.org/project/eml-parser/
https://pypi.org/project/EmailParser/
Basically msg file are just text files. (should be..., as all data is supposed to be ascii).
ASKER
Dear noci
I have probably found even better parser https://pypi.org/project/mail-parser/
It seems to be able to process file received from mondo directly from memory, without need to store it as file. I will check.
Hopefully I will be able to extract all properties I need.
Thanks
Vladimir
I have probably found even better parser https://pypi.org/project/mail-parser/
It seems to be able to process file received from mondo directly from memory, without need to store it as file. I will check.
Hopefully I will be able to extract all properties I need.
Thanks
Vladimir
My experience is that Outlook sometimes locks the file longer than it should (někdy je to na posrání). Did you try to close Outlook first and then to delete the file (using the script)?
ASKER
Dear Pepr,
it is unbelievable, but closing outlookapplication.quit() + even another 5 seconds of sleep does not help :-(((((
Thanks
V
it is unbelievable, but closing outlookapplication.quit() + even another 5 seconds of sleep does not help :-(((((
Thanks
V
Then there is some dangling reference in the win32com.client, which is not freed.
mail-parser looks ok too, just also needs perl.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
And I'm pretty sure that this method is not 100% sequential/blocking, thus I suspect you reach the remove() call before everything is really closed.
Just try a time.sleep(1) or some more seconds.