【发布时间】:2021-12-01 16:15:19
【问题描述】:
我有以下代码,当使用 eclipse 运行 python 代码时,它能够从 Outlook 读取邮件项目并下载附件。但是,当使用 pyinstaller 将相同的代码编译为 exe 时,它无法读取邮件项目并出现错误:ComObject Unknown
以下代码读取文件夹中的电子邮件项目,并从具有特定主题的邮件中下载 excel 附件。然后从下载的 xls 文件中剥离密码并将其保存为 xlsx 文件以供进一步处理。
以下代码在 eclipse 环境中运行或在命令提示符下使用 python.exe 调用时运行良好。但使用 pyinstaller 编译的 exe 运行时无法识别电子邮件项目。 我在 Exchange 服务器上使用 Windows 10 和 Outlook 2016 我在这里想念什么? 下面是代码块:
import win32com.client as wc
from datetime import date
import os
import configparser
print('Reading Config file')
config=configparser.ConfigParser()
config.sections()
config.read('ReadOutlook.config')
configuration=config['DEFAULT']
mailboxname=configuration['mailboxname']
mailfolder_to_look_for=configuration['mailfolder_to_look_for']
downloadpath=configuration['downloadpath']
ULMISPath=configuration['ULMISPath']
CFMISPath=configuration['CFMISPath']
ulmis_password=configuration['ulmis_password']
cfmis_password=configuration['cfmis_password']
ulmisSubjectcontent=configuration['ulmisSubjectcontent']
cfmisSubjectcontent=configuration['cfmisSubjectcontent']
ulmisfilenamesearch=configuration['ulmisfilenamesearch']
cfmisfilenamesearch=configuration['cfmisfilenamesearch']
print (date.today())
outlook = wc.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
root = namespace.Folders.Item(mailboxname)
print(root.Name)
#print(root.Name)
MyMails=root.Folders.Item(mailfolder_to_look_for)
def Remove_password_xlsx(filename, pw_str,newfilename):
print('opening Excel Application')
xcl = wc.Dispatch("Excel.Application")
print('opening file:' ,filename)
wb = xcl.Workbooks.Open(filename, False, False, None, pw_str)
xcl.DisplayAlerts = False
print('Removing password for',filename)
wb.SaveAs(filename, None,'','')
print('Now saving as xlsx',newfilename)
wb=xcl.Workbooks.Open(filename,False,False,None)
wb.SaveAs(newfilename, FileFormat=wc.constants.xlOpenXMLWorkbook,CreateBackup=False)
xcl.Quit()
for mailitem in range(len(MyMails.Items),0,-1):
print(MyMails.Items[mailitem].Subject)
try:
if(MyMails.Items[mailitem].ReceivedTime.date()==date.today()
and ((MyMails.Items[mailitem].Subject.find(ulmisSubjectcontent)!=-1
and MyMails.Items[mailitem].Subject.find('With Collection')!=-1)
or MyMails.Items[mailitem].Subject.find(cfmisSubjectcontent)!=-1)):
print(MyMails.Items[mailitem].Subject)
# if i.Attachments:
for f in MyMails.Items[mailitem].Attachments:
if f.FileName.find(ulmisfilenamesearch)!=-1:
f.SaveAsFile(downloadpath + '\\ULMIS.xls')
Remove_password_xlsx(downloadpath+'\\ULMIS.xls'
, ulmis_password,ULMISPath)
print('removing ULMIS.xls')
os.remove(downloadpath+'\\ULMIS.xls')
break
else:
if f.FileName.find(cfmisfilenamesearch)!=-1:
f.SaveAsFile(downloadpath + '\\CFMIS.xls')
Remove_password_xlsx(downloadpath +'\\CFMIS.xls'
, cfmis_password,CFMISPath)
print('removing CFMIS.xls')
os.remove(downloadpath+'\\CFMIS.xls')
break
except:
print('an error occurred')
pass
打印邮件主题会出现以下错误:
Traceback(最近一次调用最后一次): 文件“ReadOutlook.py”,第 45 行,模块文件 >“win32com\client\dynamic.py”,第 279 行,getitem 文件 >“win32com\client\util.py”,第 37 行,在 getitem 文件 >"win32com\client\util.py",第 56 行,在 __GetIndex IndexError: list index >out of range
IndexError: 列表索引超出范围 由于未处理的异常,无法执行脚本“ReadOutlook”!
【问题讨论】:
-
出现错误时
mailitem的值是多少?我最近在使用[]索引时遇到了类似的奇怪行为:它似乎从从零开始切换到从1 开始。尝试重新安装 pywin32 包,然后使用outlook = wc.gencache.EnsureDispatch("Outlook.Application")而不是Dispatch()。这应该会刷新 win32com 中的“胶水”代码,它将[]索引运算符转换为getitem()调用。 -
@DS_London 感谢您的回复。 mailitem 给出了正确的值 - 邮件项目的数量 - 这只是一个循环,以便我首先从最新访问数据。 outlook = wc.gencache.EnsureDispatch("Outlook.Application") 这解决了我的问题。添加上面之后,我得到了 win32timezone 的错误,我通过引用解决了这个错误:stackoverflow.com/questions/33212949/… 最后添加了 xcl=wc.gencache.EnsureDispatch("Excel.Application") 我的代码现在工作正常 - 谢谢。我如何接受这个作为答案?
标签: python outlook pyinstaller win32com mailitem