繁体   English   中英

使用 python 将 EML (MIME) 转换为 MSG

[英]Converting EML (MIME) to MSG with python

我正在尝试使用 python 将 EML 文件转换为 MSG (Outlook) 文件。 使用各种示例,我能够收集此代码,但是,它不起作用。 它会创建一个 msg 文件,但 Outlook 无法读取该文件,并且该文件的大小是输入 eml 文件的两倍。 我有点迷茫,有什么想法吗?

from win32com.mapi import mapi
from win32com.mapi import mapitags
import win32com.client
import pythoncom
from win32com import storagecon

import ctypes
import platform
import winreg
import uuid 
import sys
import os

mapi.MAPIInitialize((mapi.MAPI_INIT_VERSION, mapi.MAPI_MULTITHREAD_NOTIFICATIONS))

IconvOLE = ctypes.OleDLL(r'C:\Program Files (x86)\Microsoft Office\root\Office16\OUTLMIME.DLL')
clsid_class = uuid.UUID(str(mapi.CLSID_IConverterSession)).bytes_le
iclassfactory = uuid.UUID(str(pythoncom.IID_IClassFactory)).bytes_le
com_classfactory = ctypes.c_long(0)
IconvOLE.DllGetClassObject(clsid_class, iclassfactory, ctypes.byref(com_classfactory))
MyFactory = pythoncom.ObjectFromAddress(com_classfactory.value, pythoncom.IID_IClassFactory)
cs =  MyFactory.CreateInstance (None, str(mapi.IID_IConverterSession))

eml = mapi.OpenStreamOnFileW(r"C:\test.eml")

stg = pythoncom.StgCreateDocfile(r"C:\test.msg",
    storagecon.STGM_CREATE | storagecon.STGM_READWRITE | storagecon.STGM_TRANSACTED)

msg = mapi.OpenIMsgOnIStg(0, None, stg, None, 0, mapi.MAPI_UNICODE)

cs.MIMEToMAPI(eml, msg, win32com.mapi.mapi.CCSF_SMTP | win32com.mapi.mapi.CCSF_INCLUDE_BCC)

msg.SaveChanges(0)

mapi.MAPIUninitialize()

首先,大小并不重要,尤其是当您比较不同的文件格式时。 其次,尝试在SSView (它显示IStorage级别的数据)或OutlookSpy (我是它的作者 - 单击 OpenIMsgOnIStg 按钮)之类的实用程序中打开 MSG 文件 - 它会在 MAPI 级别显示 MSG 文件数据。

也许最重要的是,从 Outlook 2016 开始, IConverterSession接口仅在您的代码在 Outlook.exe 地址空间内运行时才有效(即您的代码是 COM/VSTO 插件或 Outlook VBA)。 此外,您的代码永远不会检查IConverterSession::MIMEToMAPI返回成功返回代码。

如果使用Redemption是一个选项(我也是它的作者),它允许在不使用 Outlook 转换器的情况下将 EML 文件转换为 MSG,就像(在 VB 脚本中)一样容易:

    set Session = CreateObject("Redemption.RDOSession")
    Session.MAPIOBJECT = Application.Session.MAPIOBJECT 'not required
    set Msg = Session.CreateMessageFromMsgFile("c:\temp\test.msg")
    Msg.Sent = true
    Msg.Import "c:\temp\test.eml", 1024 '1024 is olRfc822
    Msg.Save

所以在我从 Outlook x86 迁移到 x64 后它开始工作,我添加了以下注册表项:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{4E3A7680-B77A-11D0-9DA5-00C04FD65685}]
@="CLSID_IConverterSession"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{4E3A7680-B77A-11D0-9DA5-00C04FD65685}\InprocServer32]
@="C:\\Program Files\\Microsoft Office\\root\\Office16\\OUTLMIME.DLL"
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{9EADBD1A-447B-4240-A9DD-73FE7C53A981}]
@="CLSID_IMimeMessage"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{9EADBD1A-447B-4240-A9DD-73FE7C53A981}\InprocServer32]
@="C:\\Program Files\\Microsoft Office\\root\\Office16\\OUTLMIME.DLL"
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{9EADBD1A-447B-4240-A9DD-73FE7C53A981}\Typelib]
@="{9EADBD25-447B-4240-A9DD-73FE7C53A981}"

密钥是您可以在以下位置找到的密钥的副本:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Classes\CLSID

工作代码:

mapi.MAPIInitialize((mapi.MAPI_INIT_VERSION, mapi.MAPI_MULTITHREAD_NOTIFICATIONS))


inf = mapi.OpenStreamOnFile(r"C:\Users\xxx\raw.eml")

stg = pythoncom.StgCreateDocfile(r"C:\Users\xxx\raw.msg",
    storagecon.STGM_CREATE | storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE | storagecon.STGM_TRANSACTED)

msg = mapi.OpenIMsgOnIStg(0, None, stg, None, 0, mapi.MAPI_UNICODE)

cs = pythoncom.CoCreateInstance(mapi.CLSID_IConverterSession, None, pythoncom.CLSCTX_INPROC_SERVER, mapi.IID_IConverterSession)


cs.MIMEToMAPI(inf, msg, 0)

msg.SaveChanges(0)

mapi.MAPIUninitialize()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM