c# - 在 C# 中将 PST 转换为多个 EML 文件

标签 c# email outlook eml pst

我需要创建一个应用程序来解析 PST 文件并将邮件转换为多个 EML 文件。基本上,我需要做与 this question 中要求的相反的事情。 .

是否有实现此功能的示例代码或指南?

最佳答案

您可以使用 Outlook Redemption能够打开 PST 并将消息提取为 .EML(以及其他格式)的库。 Redemption 是一个 COM 对象(32 位或 64 位),可以毫无问题地在 C# 中使用。这是一个控制台应用程序示例代码,演示了这一点:

using System;
using System.IO;
using System.Text;
using Redemption;

namespace DumpPst
{
    class Program
    {
        static void Main(string[] args)
        {
            // extract 'test.pst' in the 'test' folder
            ExtractPst("test.pst", Path.GetFullPath("test"));
        }

        public static void ExtractPst(string pstFilePath, string folderPath)
        {
            if (pstFilePath == null)
                throw new ArgumentNullException("pstFilePath");

            RDOSession session = new RDOSession();
            RDOPstStore store = session.LogonPstStore(pstFilePath);
            ExtractPstFolder(store.RootFolder, folderPath);
        }

        public static void ExtractPstFolder(RDOFolder folder, string folderPath)
        {
            if (folder == null)
                throw new ArgumentNullException("folder");

            if (folderPath == null)
                throw new ArgumentNullException("folderPath");

            if (folder.FolderKind == rdoFolderKind.fkSearch)
                return;

            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }

            foreach(RDOFolder child in folder.Folders)
            {
                ExtractPstFolder(child, Path.Combine(folderPath, ToFileName(child.Name)));
            }

            foreach (var item in folder.Items)
            {
                RDOMail mail = item as RDOMail;
                if (mail == null)
                    continue;

                mail.SaveAs(Path.Combine(folderPath, ToFileName(mail.Subject)) + ".eml", rdoSaveAsType.olRFC822);
            }
        }

      /// <summary>
      /// Converts a text into a valid file name.
      /// </summary>
      /// <param name="fileName">The file name.</param>
      /// <returns>
      /// A valid file name.
      /// </returns>
      public static string ToFileName(string fileName)
      {
          return ToFileName(fileName, null, null);
      }

      /// <summary>
      /// Converts a text into a valid file name.
      /// </summary>
      /// <param name="fileName">The file name.</param>
      /// <param name="reservedNameFormat">The reserved format to use for reserved names. If null '_{0}_' will be used.</param>
      /// <param name="reservedCharFormat">The reserved format to use for reserved characters. If null '_x{0}_' will be used.</param>
      /// <returns>
      /// A valid file name.
      /// </returns>
      public static string ToFileName(string fileName, string reservedNameFormat, string reservedCharFormat)
      {
          if (fileName == null)
              throw new ArgumentNullException("fileName");

          if (string.IsNullOrEmpty(reservedNameFormat))
          {
              reservedNameFormat = "_{0}_";
          }

          if (string.IsNullOrEmpty(reservedCharFormat))
          {
              reservedCharFormat = "_x{0}_";
          }

          if (Array.IndexOf(ReservedFileNames, fileName.ToLowerInvariant()) >= 0 ||
              IsAllDots(fileName))
              return string.Format(reservedNameFormat, fileName);

          char[] invalid = Path.GetInvalidFileNameChars();

          StringBuilder sb = new StringBuilder(fileName.Length);
          foreach (char c in fileName)
          {
              if (Array.IndexOf(invalid, c) >= 0)
              {
                  sb.AppendFormat(reservedCharFormat, (short)c);
              }
              else
              {
                  sb.Append(c);
              }
          }

          string s = sb.ToString();

          // directory limit is 255
          if (s.Length > 254)
          {
              s = s.Substring(0, 254);
          }

          if (string.Equals(s, fileName, StringComparison.Ordinal))
          {
              s = fileName;
          }
          return s;
      }

      private static bool IsAllDots(string fileName)
      {
          foreach (char c in fileName)
          {
              if (c != '.')
                  return false;
          }
          return true;
      }

      private static readonly string[] ReservedFileNames = new[]
      {
          "con", "prn", "aux", "nul",
          "com0", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
          "lpt0", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"
      };
    }
}

关于c# - 在 C# 中将 PST 转换为多个 EML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14154492/

相关文章:

excel - 自动电子邮件中的时间格式是 "general"而不是 hh :nn AM/PM

c# - 带有 WellKnownText 空间数据列的 SqlBulkCopy DataTable

c# - 继承的 Windows 窗体奇怪行为

c# - 将word文档转换为xml代码c#

email - 为什么 “-”(连字符)是电子邮件兼容性的唯一 ASCII 限制?

vba - 将项目限制为 BillingInformation 为空的项目

c# - 如何删除 URL 中的占位符

html - PIE.htc hack 在电子邮件中有效吗?

python:如何更改 Outlook 获取创建时间格式?

c# - 如何将电子邮件从 Outlook 拖放到 .NET 应用程序中?