在C#中将多个eml文件转换为单个PST我需要编写一个函数,它将获取多个eml文件(可能来自单个文件系统文件夹)并转换它们转换成单独的PST文件。是否可以?如果是,有人可以提供示例代码吗?我认为这可能是因为有许多商业eml到pst转换器可以执行此操作,虽然Outlook可以打开EML文件,但无法仅使用VBA以编程方式执行此操作。所以我创建了这个VBA宏,它循环遍历某个文件夹并使用SHELLEXEC打开每个EML文件。在Outlook打开EML文件之前可能需要几毫秒,因此VBA会一直等到在ActiveInspector中打开某些内容。最后,将此电子邮件复制到某个选定的文件夹,并且(如果成功)删除原始EML文件。此宏有时会崩溃,但您可以随时重新启动宏,它会从之前崩溃的地方重新启动(请记住,所有成功导入的EML文件都将被删除)。如果重启后还是死机,可能是下一个要导入的EML文件有问题。在这种情况下,您可以删除有问题的EML。PS:有时你可以自己打开EML而不会导致Outlook崩溃,但根据我的测试,每次EML文件崩溃都不重要,就像阅读回执一样。这是我的VBA代码。如果您有任何疑问或问题,请告诉我。'---------------------------------------------------'RicardoDrizin的代码(联系信息位于http://www.drizin.com.br)'--------------------------------------------------PrivateDeclarePtrSafeSubSleepLib"kernel32"(ByValdwMillisecondsAsLong)OptionExplicit'-----------------------------------------------------------------'此方法关闭ActiveInspectors(如果有)。'所有导入都是基于EML'由shell打开的假设,我们可以通过ActiveInspector引用它'------------------------------------------------------------------函数CloseOpenInspectors()AsBooleanDimappAsOutlook.Application:Setapp=CreateObject("Outlook.Application")DiminspAsOutlook.InspectorDimcountAsIntegercount=0重复:count=count+1Setinsp=app.ActiveInspectorIfTypeName(insp)="Nothing"ThenCloseOpenInspectors=TrueExitFunctionEndIfIfTypeName(insp.CurrentItem)="Nothing"ThenCloseOpenInspectors=TrueExitFunctionEndIfIf(count>100)ThenMsgBox“错误。无法关闭ActiveInspector。”CloseOpenInspectors=FalseEndIfinsp.Close(olDiscard)GoTorepeatEndFunction'----------------------------------------------------------------'此方法允许用户在Outlook中选择一个根文件夹'所有EML文件都将导入到该文件夹??下'-------------------------------------------------------------------函数GetRootFolder()AsOutlook.folderDimappAsOutlook.Application:Setapp=CreateObject("Outlook.Application")DimNSAsOutlook.NameSpace:SetNS=app.GetNamespace("MAPI")DimfoldAsOutlook。folderSetfold=NS.PickFolder'MsgBoxfold.NameSetGetRootFolder=foldEndFunction'----------------------------------------------------------------------'在Outlook中的根文件夹下创建一个子文件夹。'------------------------------------------------------------------函数GetChildFolder(parentFolderAsOutlook.folder,nameAsString)OnErrorResumeNextDimfold2AsOutlook.folderSetfold2=parentFolder.folders.Item(name)IfErr.NumberThenOnErrorGoTo0设置fold2=parentFolder.folders.Add(name)EndIfOnErrorGoTo0'MsgBoxfold2.NameSetGetChildFolder=fold2EndFunction'------------------------------------------------------------------'导入在当前ActiveInspector中打开的EML'进入给定的文件夹'------------------------------------------------------------------SubImportOpenItem(targetFolderAsOutlook.folder)DimappAsOutlook.Application:Setapp=CreateObject("Outlook.Application")DiminspAsOutlook.Inspector:Setinsp=app.ActiveInspectorDimretriesAsIntegerretries=0WhileTypeName(insp)="Nothing"'阅读窗格应该可见,否则它将不起作用。'MsgWaitObj(1000)Sleep(50)DoEventsSleep(50)Setinsp=app.ActiveInspectorretries=retries+1'Ifretries>100Then'Stop'EndIfWendIfTypeName(insp)="Nothing"ThenMsgBox"Error!Couldnotfindopeninspectorforimportingemail."退出SubEndIfDimmAsMailItem,m2AsMailItem,m3AsMailItemSetm=insp.CurrentItem'MsgBoxm.SubjectSetm2=m.CopySetm3=m2.Move(targetFolder)m3.SaveSetm=NothingSetm2=NothingSetm3=Nothinginsp.Close(olDiscard)Setinsp=NothingEndSub'------------------------------------------------------------------'扫描给定文件夹中的*.EML文件和将它们导入给定的文件夹。'每个EML文件将在导入后被删除。'------------------------------------------------------------------SubImportEMLFromFolder(targetFolderAsOutlook.folder,emlFolderAsString)IfRight(emlFolder,1)""ThenemlFolder=emlFolder&""DimfirstImportAsBoolean:firstImport=TrueDimfileAsStringDimcountAsInteger:count=0'MsgBoxfold.Items.count'退出子文件=Dir(emlFolder&"*.eml")repeat:Iffile=""Then'MsgBox"FinishedimportingEMLfiles.Total="&countDebug.Print"FinishedimportingEMLfiles.Total="&countExitSubEnd如果计数=计数+1Debug.Print"Importing..."&file&"-"&emlFolderShell("explorer"""&emlFolder&file&"""")'IffirstImportThenStopfirstImport=FalseSleep(50)出错GoTonextfileCallImportOpenItem(targetFolder)CallKill(emlFolder&file)nextfile:OnErrorGoTo0Sleep(50)file=Dir()GoTorepeatEndSub'-----------------------------------------------------------------'主要方法。'用户选择Outlook根文件夹和Windows资源管理器根文件夹。'将导入此文件夹和直接子文件夹中的所有EML文件。'------------------------------------------------------------------SubImportAllEMLSubfolders()CallCloseOpenInspectorsMsgBox"选择一个根文件夹importing"DimrootOutlookFolderAsOutlook.folderSetrootOutlookFolder=GetRootFolder()IfrootOutlookFolderIsNothingThenExitSubDimrootWindowsFolderAsStringrootWindowsFolder="D:OutlookExpressEMLs文件夹"rootWindowsFolder=InputBox("选择你有EML文件的Windows文件夹",,rootWindowsFolder)IfIsNull(rootWindowsFolder)或IsEmpty(rootWindowsFolder)或rootWindowsFolder=""ThenExitSubIfRight(rootWindowsFolder,1)""ThenrootWindowsFolder=rootWindowsFolder&""DimsubFoldersAsNewCollectionDimsubFolderAsStringsubFolder=Dir(rootWindowsFolder,vbDirectory)重复:如果subFolder="."或subFolder=".."ThenGoTonextdirIf(GetAttr(rootWindowsFolder&subFolder)AndvbDirectory)=0ThenGoTonextdirsubFolders.Add(subFolder)nextdir:subFolder=Dir()IfsubFolder""ThenGoTorepeatDimoutlookFolderAsOutlook.folder'导入主文件夹CallImportEMLFromFolder(rootOutlookFolder,rootWindowsFolder)'导入子文件夹WhilesubFolders.countsubFolder=subFolders.Item(1)subFolders.Remove(1)SetoutlookFolder=GetChildFolder(rootOutlookFolder,subFolder)Debug.Print"Importing"&rootWindowsFolder&subFolder&"intoOutlookfolder"&outlookFolder.name&"..."CallImportEMLFromFolder(outlookFolder,rootWindowsFolder&subFolder)WendDebug.Print"Finished"EndSub可能是简单或更好的方法,但一种方法可能是使用Interop自动化Outlook可能有一些使用Outlook的内置导入功能的能力将是我尝试寻找的第一件事。假设这不可能,您仍然可以通过读取应用程序中的eml文件然后通过Interop创建邮件项来完成。通常eml文件只是MIME格式的文本文件,因此只需将它们作为文本文件读取并解析即可。这是一篇关于从C#解析MIME的文章,否则只要搜索“POP3C#”,您就会找到其他文章。然后按照此处所述使用命名空间Microsoft.Office.Interop.OutlookOutlookInterop。我猜你可能必须先创建一个Application对象,然后使用它来获取Store对象(我认为每个PST文件都是一个Store),然后是那里的Folder,然后找到一些方法来创建MailItem使用从eml文件中获得的解析数据。本文介绍如何使用Outlook自动创建联系人和约会,可能会有用。您可以使用赎回。一些东西:setSession=CreateObject("Redemption.RDOSession")Session.LogonPstStore("c:temptest.pst")setFolder=Session.GetDefaultFolder(olFolderInbox)setMsg=Folder.Items.Add("IPM.Note")Msg.Sent=trueMsg.Import("c:temptest.eml",1024)Msg.Save您可以在此处找到pst文件格式的规范。但我认为您会花一些时间将它们放在一起,自己创建一个eml->pst解析器。但它应该是可能的。以上就是C#学习教程:在C#中将多个eml文件转换为单个PST共享。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收藏,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
