I am looping through entryIds stored in a dataframe (loaded from a csv file) and accessing the messages by dispatching win32com.client to access Outlook MAPI and save email attachments to a local directory using the below code. I also am storing the attachment name, path, and entryId in a new dataframe for later analysis.
- Outlook version: 2202 (Build 14931.20764)
- Pywin32 version: 227
- Python version: 3.7.1
df = pd.DataFrame(columns=['attName', 'path', 'entryId'])
id = 1
for email in emailData.itertuples():
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
message = outlook.GetItemFromID(email.entryId)
if message:
receivedDate = message.ReceivedTime
if message.Attachments.Count > 0:
for attachment in message.Attachments:
if attachment.Type in {1,4,5}:
if not attachment.DisplayName.endswith('.png') and not attachment.DisplayName.endswith('.jpg') and not attachment.DisplayName.endswith('.gif'):
attName = str(attachment.DisplayName)
print('\t Attachment: %s' % attachment.DisplayName)
path = "some directory\\%s\\%s" % (receivedDate.year, attachment.DisplayName)
attachment.SaveAsFile(path) #if I remove this line, the error no longer occurs
attachment = None
df.loc[id] = ([attName, str(path), email.entryId])
id += 1
attachments = None
message.Close(1)
outlook.Logoff()
outlook = None
Once I have scanned 248 messages, I encounter the below error regardless of the particular message:
File "C:\Anaconda3\envs\myenv\lib\site-packages\win32com\client\__init__.py", line 474, in __getattr__
return self._ApplyTypes_(*args)
File "C:\Anaconda3\envs\myenv\lib\site-packages\win32com\client\__init__.py", line 467, in _ApplyTypes_
self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args),
pywintypes.com_error: (-2147352567, 'Exception occurred.', (4096, 'Microsoft Outlook', 'Your server administrator has limited the number of items you can open simultaneously. Try closing messages you have opened or removing attachments and images from unsent messages you are composing.', None, 0, -2147220731), None)
I am able to isolate the error specifically to this line:
attachment.SaveAsFile(path)
If I remove this line, the error goes away and will continue scanning messages. I am not sure what is causing this error and I have tried various commands to close/remove references to the attachments by setting objects to None and using outlook.Logoff() for the namespace.
Has anyone else encountered this issue or have any way to resolve it?
UPDATE: After reading Eugene Astafiev's helpful suggestions, I've made some updates to my code to help show that the issue is specifically with the attachment.SaveAsFile(path) line. Unfortunately, I still receive the exact same error. Maybe I am not understanding how to release the objects? can anyone help further?
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
for email in emailData.itertuples():
message = outlook.GetItemFromID(email.entryId)
if message:
attachments = []
for attachment in list(message.Attachments):
attachments.append(attachment)
for attachment in attachments:
attachType = int(attachment.Type)
if attachType in {1,4,5}:
attName = str(attachment.DisplayName)
if not attName.endswith('.png') and not attName.endswith('.jpg') and not attName.endswith('.gif'):
path = "somedir\\%s" % (attName)
attachment.SaveAsFile(path) #Error disappears if this line is removed
del attachment
del path
del attName
del attachType
del attachments
message.Close(1)
del message