使用 Outlook HTML 模板 (*.oft) 在 VB.Net 中创建的电子邮件在发送时转换为纯文本

问题描述 投票:0回答:0

我在下面的实施中遇到问题。该脚本对先前选择的文件夹 (oFolder) 中的所有邮件进行循环,直到该文件夹中没有更多邮件 (MailItem),它才会循环并发送回复。但是从模板(*.oft - Outlook 模型)创建的消息在发送后会转换为纯文本,除非发送到内部电子邮件地址,与发件人在同一域中,然后格式保持不变。

我尝试了一些解决方案,例如在创建消息后重置 .HTMLBody,但无济于事。也许我把解决方案放在错误的地方,不确定。但这是我的代码:

Dim originalMail, loopControl, newMail, headerMail, footerMail As MailItem
Dim snd2Folder As MAPIFolder
Dim myRecipient As Recipients
Dim thisRecipient As Recipient
Dim oSubject, oMessage, oMessageNew, oRecipient, oMailDate, oMailTo, thisSenderAddr, tempTemplate As String
Dim objPropNewName, objPropNewDateTime As UserProperty
Dim thisClassName As Type


While oFolder.Items.Count > 0
    loopControl = oFolder.Items.GetFirst
    If TypeName(loopControl) = "MailItem" Then 
        originalMail = loopControl 

        originalMail.BodyFormat = OlBodyFormat.olFormatHTML 'here tried implementing the post solution, not working
        originalMail.HTMLBody = originalMail.HTMLBody
        originalMail.Save()

        myRecipient = originalMail.ReplyRecipients 'the original message comes from a form in a web page, that contains the persons email set in the Reply-To field

        newMail = OutlookApp.CreateItemFromTemplate(tempTemplate) 'creates a new message from a template in the tempTemplate location, a local folder with *.oft files selected by the user

        objPropNewName = newMail.UserProperties.Add("Custom Property", OlUserPropertyType.olText, True) 'sensitive custom property set by the organisation for control purposes
        objPropNewName.Value = tmpUserName 'value to be stored in the property
        objPropNewDateTime = newMail.UserProperties.Add("Another Custom Property", OlUserPropertyType.olDateTime, True)
        objPropNewDateTime.Value = tmpDateTime

        If originalMail.ReplyRecipients.Count > 0 Then 'since the message may come from a web form or directly via Replay, it is important to get the SMTP email address in the .To field. This block makes sure the .To field will get a valid SMTP address
            Try
                thisRecipient = myRecipient.Item(1)
                thisRecipient.Resolve()
                If thisRecipient.Resolved() Then
                    thisUser = thisRecipient.AddressEntry.GetExchangeUser()
                    If thisUser Is Nothing Then
                        oRecipient = myRecipient.Item(1).Address.ToString()
                    Else
                        oRecipient = thisRecipient.AddressEntry.GetExchangeUser.PrimarySmtpAddress.ToString()
                    End If
                Else
                    oRecipient = myRecipient.Item(1).Address.ToString()
                End If
                'oRecipientMail = myRecipient.Item(1).AddressEntry.Address.ToString() 
            Catch ex As System.Exception
                PrintCurrentLineException(ex, thisClassName.FullName, MethodBase.GetCurrentMethod().Name)
                oRecipient = myRecipient.Item(1).Address.ToString() 'if there is an error because the sender is not a Exchange user, it will be a SMTP address, so get that value instead
            End Try
        Else
            If originalMail.SenderEmailType = "EX" Then
                oRecipient = originalMail.Sender.GetExchangeUser.PrimarySmtpAddress.ToString()
            Else
                oRecipient = originalMail.SenderEmailAddress 
            End If
        End If

        With originalMail 
            oSubject = .Subject 
            oMessage = .HTMLBody 
            oMailTo = .To
            oMailDate = Format(.SentOn, "dddd, dd MMM yyyy - HH:mm")
        End With

        If originalMail.ReadReceiptRequested = True Or originalMail.OriginatorDeliveryReportRequested = True Then
            Dim thisEntry, thisSubject, thisDate As String
            Dim thisAccessor As PropertyAccessor
            thisAccessor = originalMail.PropertyAccessor
            thisEntry = thisAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x1035001E").ToString()
            thisSubject = originalMail.Subject
            thisDate = Format(originalMail.SentOn, "ddd dd/MM/yyyy HH:mm")
            OBGWorkerModulo1.CancelAsync()
            Thread.Sleep(300)
            MsgBox("One of the messages in this lot of " & i1 & " messages have a delivery or a read recipe active." & vbNewLine & vbNewLine & "The application cannot work correctly. Please mark the message as read or reply to it manually." & vbNewLine & vbNewLine & "Sender: " & oRecipient & vbNewLine & "Subject: " & thisSubject & vbNewLine & "Received in: " & thisDate & vbNewLine & "Message EntryID: " & thisEntry, vbDefaultButton1 + vbExclamation + vbOKOnly + vbApplicationModal + vbMsgBoxSetForeground, "Read/Delivery Recipe")
            errorLocal = True 'variable to point an internal error
            Exit Try
        End If

        With newMail 
            .To = oRecipient 
            .Subject = oSubject 
            thisSenderAddr = LCase(outServer) '
            Try
                If tmpChkHeader = True And tmpChkFooter = False Then 'an internal option to set header or/and footer as a template to be applied to the reply message
                    oMessageNew = "<html><style>body {font-family: calibri; font-size: 11.25pt;}</style>" & headerMail.HTMLBody & newMail.HTMLBody & "<body><br><hr>" & "---- Your message ----<br><b>From:</b><a href="" mailto:" & oRecipient & """>" & oRecipient & "</a><br><b>Sent on:</b> " & oMailDate & "<br><b>To:</b> " & oMailTo & " (<a href=""mailto:" & thisSenderAddr & """>" & thisSenderAddr & "</a>)<br><b>Subject:</b> " & oSubject & "<br><br><blockquote>" & oMessage & "</blockquote></body></html>" 
                ElseIf tmpChkHeader = False And tmpChkFooter = True Then
                    oMessageNew = "<html><style>body {font-family: calibri; font-size: 11.25pt;}</style>" & newMail.HTMLBody & footerMail.HTMLBody & "<body><br><hr>" & "---- Your message ----<br><b>From:</b><a href="" mailto:" & oRecipient & """>" & oRecipient & "</a><br><b>Sent on:</b> " & oMailDate & "<br><b>To:</b> " & oMailTo & " (<a href=""mailto:" & thisSenderAddr & """>" & thisSenderAddr & "</a>)<br><b>Subject:</b> " & oSubject & "<br><br><blockquote>" & oMessage & "</blockquote></body></html>" 
                ElseIf tmpChkHeader = True And tmpChkFooter = True Then
                    oMessageNew = "<html><style>body {font-family: calibri; font-size: 11.25pt;}</style>" & headerMail.HTMLBody & newMail.HTMLBody & footerMail.HTMLBody & "<body><br><hr>" & "---- Your message ----<br><b>From:</b><a href="" mailto:" & oRecipient & """>" & oRecipient & "</a><br><b>Sent on:</b> " & oMailDate & "<br><b>To:</b> " & oMailTo & " (<a href=""mailto:" & thisSenderAddr & """>" & thisSenderAddr & "</a>)<br><b>Subject:</b> " & oSubject & "<br><br><blockquote>" & oMessage & "</blockquote></body></html>" 
                Else
                    oMessageNew = "<html><style>body {font-family: calibri; font-size: 11.25pt;}</style>" & newMail.HTMLBody & "<body><br><hr>" & "---- Your message ----<br><b>From:</b><a href="" mailto:" & oRecipient & """>" & oRecipient & "</a><br><b>Sent on:</b> " & oMailDate & "<br><b>To:</b> " & oMailTo & " (<a href=""mailto:" & thisSenderAddr & """>" & thisSenderAddr & "</a>)<br><b>Subject:</b> " & oSubject & "<br><br><blockquote>" & oMessage & "</blockquote></body></html>" 
                End If
            Catch ex As System.Exception
                PrintCurrentLineException(ex, thisClassName.FullName, MethodBase.GetCurrentMethod().Name)
                oMessageNew = "<html><style>body {font-family: calibri; font-size: 11.25pt;}</style>" & newMail.HTMLBody & "<body><br><hr>" & "---- Your message ----<br><b>From:</b><a href="" mailto:" & oRecipient & """>" & oRecipient & "</a><br><b>Sent on:</b> " & oMailDate & "<br><b>To:</b> " & oMailTo & " (<a href=""mailto:" & thisSenderAddr & """>" & thisSenderAddr & "</a>)<br><b>Subject:</b> " & oSubject & "<br><br><blockquote>" & oMessage & "</blockquote></body></html>" 
            End Try
            .SentOnBehalfOfName = outServer 'server mail set on a config file
            .HTMLBody = oMessageNew
            .Send() 
        End With
        
        If sndReply = True Then 'if the sent event is all right, this variable is set to true       
            originalMail.Unread = False 
            originalMail.Move(snd2Folder) 'a outlook folder to where the original messages are moved after replied to
            Marshal.ReleaseComObject(originalMail)
            Marshal.ReleaseComObject(newMail)
            Marshal.ReleaseComObject(objPropNewName)
            Marshal.ReleaseComObject(objPropNewDateTime)
        End If

        intCnt += 1
            i2 += 1
    Else
        Dim controlTypeName As String = Information.TypeName(loopControl)
        MsgBox("One item in the selected folder is not a valid email message. Remove the item to another folder or select another folder before running this lot again." & vbNewLine & vbNewLine & "Control Type: " & controlTypeName & vbNewLine & $"Selected folder: {oFolder.Name}", vbDefaultButton1 + vbExclamation + vbOKOnly + vbApplicationModal + vbMsgBoxSetForeground, "Wrong control type")
        errorLocal = True
        Exit Try
    End If
End While

我已经尝试过这篇文章中的解决方案,但到目前为止没有运气:

使用模板在 VBA 中创建的 Outlook 电子邮件在保存时转换为纯文本

我有一个非常相似的代码,没有在发送后保持格式的循环。

主要区别在于上面的代码在发送前不显示消息,因为它会减慢进程(必须在发送前显示每条消息)。

有没有一种显示而不显示的方法,比如命令消息在发送前按照模板中的方式进行格式化?

html vb.net email outlook
© www.soinside.com 2019 - 2024. All rights reserved.