【问题标题】:Outlook ReportItem.Body returning messed up encodingOutlook ReportItem.Body 返回混乱的编码
【发布时间】:2022-04-19 23:55:05
【问题描述】:

如果某些用户自动化 Outlook 客户端以查看共享收件箱中的退回邮件/ReportItems,而不是按照文档中的指示返回邮件的明文文本,则会有一个已被解析为 UTF-8 字符串的 unicode 字符串- 所以它看起来像中文。

我可以通过一些代码来解决这个问题,但另一个问题是,对于所有有权访问该收件箱的用户,Outlook 中也会发生这种变化。在 Outlook 中查看的邮件本身显示为中文字符 - 原始 unicode html 被解析为 UTF-8。

我们正在使用正常的方法来访问报告项:

For Counter as Integer = Inbox.Items.Count To 1 Step -1
    Dim Report As Outlook.ReportItem = Inbox.Items(Counter)
    Dim Body As String = Report.Body

最后一行是我们得到乱码文本的地方。在 VBA 中,它尝试将其解析为 ASCII 并返回一大块“?”。在 .Net 中,它返回解析为 UTF-8 的值,我们得到显示为中文的字符。在任何一种情况下,收件箱中的报告项都会开始显示为中文字符,并将继续为该收件箱的所有用户显示。

【问题讨论】:

    标签: vb.net vba encoding outlook exchange-server


    【解决方案1】:

    我刚刚在 Outlook 中的 VBA 函数中发生了这种情况,该函数处理订单的电子邮件退回并将这些订单标记为需要注意。 Outlook 中的原始电子邮件看起来不错,但是当我尝试处理它时,字符变为中文并且 Report.Body 只显示问号。

    我发现使用 StrConv 转换为 Unicode 可以获得正确的正文内容以进行处理。

    Dim strBody as String
    strBody = StrConv(Report.Body, vbUnicode)
    

    【讨论】:

    • 这几乎也是我发现的,由于某种原因,unicode 显示为 UTF8。我的问题仍然存在。我们可以通过编程方式访问消息,但我们仍然需要能够以人类可读的方式将消息放入收件箱中,所以我所追求的是不会导致问题开始的东西。
    • 这是我使用的 c# 等效项:System.Text.Encoding.UTF8.GetString(new UnicodeEncoding().GetBytes(report.Body))
    • StrConv( vbUnicode ) 在 .NET 中不存在。这是我使用的等价物:Function UnsquishString(ByVal squished As String) As String Dim len As Double = str.Length * 2.0 Dim b(len - 1) As Byte System.Buffer.BlockCopy(str.ToCharArray(), 0, b, 0, b.Length) Return System.Text.Encoding.GetEncoding(1252).GetString(b) End Function
    【解决方案2】:

    您确定 Inbox.Items(Counter) 调用返回 ReportItem 类的实例吗?您有机会查看 MessageClass 属性吗?

    您很可能尝试将 MailItem 类的实例强制转换为 ReportItem 类。是这样吗?

    我还建议使用任何低级属性查看器(例如 MFCMAPI 或 OutlookSpy)在运行时观察属性。你在那里看到“中文”字符吗?

    【讨论】:

    • 我上面提供的例子有点简单,但我使用反射来检查代码中项目的类型。在这种情况下,该代码被设置为在仅包含 1 个报告项的收件箱上运行。抱歉,如果这引起了任何混乱。实际上,我正在考虑切换到 Exchange Web 服务。我们已经远离了这一点,因为我们不是 IT 部门的一部分,而且他们担心我们会更多地挖掘他们的系统。
    • 另外,要明确一点,中文真的只是解析错误。获取一个 unicode 流并将其解析为 UTF-8,您就会明白我的意思。抓取任何带有一些英文的任意 HTML 文档,并获取 unicode 字节并解析为 UTF-8。你会看到一些看起来像“中国人”的东西。这就是我们在运行代码后查看报告项时在我们的应用程序和 Outlook 中看到的内容。
    【解决方案3】:

    我遇到了这个问题,我编写了一个函数来为我解决这个问题。我想我会在这里分享它以防其他人使用它。

    Private Sub Example()
        Dim Item As Object
        
        Set Item = Application.ActiveExplorer.Selection(1)
        
        Debug.Print ItemBody(Item)
    End Sub
    
    Public Function ItemBody(Item As Variant) As String
    On Error Resume Next
        If TypeName(Item) = "ReportItem" Then
            With Item.GetInspector
                ItemBody = .WordEditor.Content
                .Close 1
            End With
        Else
            ItemBody = Item.Body
        End If
    End Function
    

    【讨论】:

      【解决方案4】:

      是的,Outlook 对象模型中的 ReportItem.Body 属性存在问题(存在于 Outlook 2013 和 2016 中) - 您可以在 OutlookSpy 中看到它(我是它的作者):选择 NDR 邮件,单击项目按钮,选择 Body 属性——它会出现乱码。更糟糕的是,一旦使用 OOM 触摸报表项,Outlook 将在预览窗格中显示相同的垃圾。

      报告文本存储在各种 MAPI 收件人属性中(单击 OutlookSpy 中的 IMessage 按钮并转到 GetRecipientTable 选项卡)。问题是 ReportItem 对象没有公开 Recipients 集合。解决方法是使用扩展 MAPI(C++ 或 Delphi)或 Redemption(任何语言 - 我也是它的作者) - 它的 ReportItem.ReportText 属性没有这个问题:

      set oItem = Application.ActiveExplorer.Selection(1)
      set oSession = CreateObject("Redemption.RDOSession")
      oSession.MAPIOBJECT = Application.Session.MAPIOBJECT
      set rItem = oSession.GetRDOObjectFromOutlookObject(oItem)
      MsgBox rItem.ReportText
      

      【讨论】:

        猜你喜欢
        • 2020-10-05
        • 2015-03-18
        • 2012-04-13
        • 2015-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-21
        • 1970-01-01
        相关资源
        最近更新 更多