none
Stream signature which contains text & an image into an outlook message RRS feed

  • Question

  • Hi Gurus,

    I hope this is addressed to the correct forum. I recently started converting from Access VBA to VB.Net winforms & one of the functions I have is as shown here which worked wonderfully when I had a purely text signature. In the interim I've included an image. When I manually type & send a message from Outlook the signature is as expected but being sent by code this produces a text stream & I need help changing it to include the jpg image. Can a helpful person direct me on this please?

        Function GetBoiler(ByVal sFile As String) As String
            'Dick Kusleika
            Dim fso As Object = Nothing
            Dim ts As Object = Nothing
    
            Try
                fso = CreateObject("Scripting.FileSystemObject")
                ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
                'GetBoiler = ts.ReadAll
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
    
            GetBoiler = ts.ReadAll
            fso = Nothing
            ts = Nothing
    
        End Function

    Friday, February 8, 2019 2:30 PM

All replies

  • If you are handing signatures explicitly in your code, it is your responsibility to parse the HTML, find all img and imagedata tags, figure out which signature image they refer to, add that image as an attachment, set PR_ATTACH_CONTENT_ID on that attachment, then modify the HTML image tag to point to that attachment via the src=cid:xyz attribute (where xyz is the value of the PR_ATTACH_CONTENT_ID property on the attachment).

    If using Redemption is an option, it exposes RDOSignature.ApplyTo method which tkes care of that (as well as a few other things, such as merging the two HTML styles).


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, February 8, 2019 3:06 PM
  • Hello Dimitry,

    Thanks for responding. I'm slowly getting into a bit of HTML & xml so have a lot to learn & at this stage this is still beyond my capabilities. I will do more research until I get it right since I don't give up easily. At first I found Outlook a challenge when I started in VBA. I'm not using Redemption as I'm doing this for a non profit organization.

    I do have this piece of code to establish the path & Signature of the user however but wouldn't know how to progress from there at this stage

    If Left$(SYSversion, 19) = "Microsoft Windows 7" Or Left$(SYSversion, 19) = "Microsoft Windows 8" Or Left$(SYSversion, 20) = "Microsoft Windows 10" Then
                Return appdata & "\Microsoft\Signatures\" & My.Settings.EmailSignature
    where signature is something.htm


    Friday, February 8, 2019 4:13 PM
  • I've now had a chance to work on this a bit again & have the following bits of info using these bits of code. What I need to establish now is how to get the image in the signature to point to my oAttach object

    Can a helpful soul point a novice to achieving that

        Const PR_ATTACH_MIME_TAG = "http://schemas.microsoft.com/mapi/proptag/0x370E001E"
        Const PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001E"
        Const PR_ATTACHMENT_HIDDEN = "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B"

    oAttach = .Attachments.Add(sigpath() & "_files\image001.jpg") .Subject = strSubj If IsHtmlFormat And Embedded = True Then .HTMLBody = strBody & "<br><br>" & .HTMLBody & "<br><br>" & Signature ElseIf IsHtmlFormat = False And Embedded = True Then .HTMLBody = WebUtility.HtmlEncode(strBody) & "<br><br>" & WebUtility.HtmlEncode(.HTMLBody) & "<br><br>" & Signature ElseIf IsHtmlFormat Then oAttach.PropertyAccessor.SetProperty(PR_ATTACH_MIME_TAG, "image/jpg") oAttach.PropertyAccessor.SetProperty(PR_ATTACH_CONTENT_ID, "image001.jpg@01D4C54F.EF900B70") oAttach.PropertyAccessor.SetProperty(PR_ATTACHMENT_HIDDEN, True) .HTMLBody = strBody.Replace(vbCrLf, "<br>") & "<br><br>" & "<p></p>" & "<img width=85 height=85 src=cid:image001.jpg@01D4C54F.EF900B70 align=left hspace=12 v:shapes=Picture_x0020_1>" & Signature

    When I run it the result looks like this

    OutlookSpy give me this

    And the source code of the email body is the following:-

    <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=iso-8859-1"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><!--[if !mso]><style>v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style><![endif]--><style><!-- /* Font Definitions */ @font-face     {font-family:Calibri;     panose-1:2 15 5 2 2 2 4 3 2 4;} @font-face     {font-family:"Monotype Corsiva";     panose-1:3 1 1 1 1 2 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal     {margin:0cm;     margin-bottom:.0001pt;     font-size:11.0pt;     font-family:"Calibri","sans-serif";     } a:link, span.MsoHyperlink     {     color:blue;     text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed     {     color:purple;     text-decoration:underline;} span.EmailStyle17     {     font-family:"Calibri","sans-serif";     color:windowtext;} .MsoChpDefault     {     font-family:"Calibri","sans-serif";     } @page WordSection1     {size:612.0pt 792.0pt;     margin:72.0pt 72.0pt 72.0pt 72.0pt;} div.WordSection1     {page:WordSection1;} --></style><!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="1027" /> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1" /> </o:shapelayout></xml><![endif]--></head><body lang=EN-ZA link=blue vlink=purple><div style='font-size:14.0pt;font-family:"Monotype Corsiva";color:#002060;<o:p><span style='text-decoration:none'>&nbsp;</span></o:p></span></u></p><p style='font-size:14.0pt;font-family:"Monotype Corsiva";color:#002060;<o:p><span style='text-decoration:none'>&nbsp;</span></o:p></span></u></p><p gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="Picture_x0020_3" o:spid="_x0000_s1026" type="#_x0000_t75" style=';margin-left:0;margin-top:52.5pt;width:63.75pt;height:63.75pt;z-index:251659264;visibility:visible;"f"> <v:imagedata src="cid:image001.jpg@01D4C54F.EF900B70" o:title="" /> <w:wrap type="square" anchory="line"/> </v:shape><![endif]--><![if !vml]><img width=85 height=85 src="cid:image002.jpg@01D4C54F.EF900B70" align=left hspace=12 v:shapes="Picture_x0020_3"><![endif]><u><span style='font-size:14.0pt;font-family:"Monotype Corsiva";color:#002060;Hugh Naudé (SADTA Points Status Secretary)<o:p></o:p></span></u></p><p style='font-family:"Monotype Corsiva";color:purple;Cell:&nbsp;&nbsp; 072 697 5846<o:p></o:p></span></p><p style='font-family:"Monotype Corsiva";color:purple;Fax:&nbsp;&nbsp; </span><span lang=EN-US style='font-family:"Monotype Corsiva";color:purple;0866381772</span><span style='font-family:"Monotype Corsiva";color:#7030A0;<o:p></o:p></span></p><p style='<o:p>&nbsp;</o:p></span></p><p style='<o:p>&nbsp;</o:p></span></p><p id="DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2"> <br /><br /> <hr style='border:none; color:#909090; background-color:#B0B0B0; height: 1px; width: 99%;' /> <table style='border-collapse:collapse;border:none;'>     <tr>         <td style='border:none;padding:0px 15px 0px 8px'>             <a href="https://www.avg.com/internet-security">                 <img border=0 src="https://static.avast.com/emails/avg-mail-stamp.png" alt="AVG logo" />             </a>         </td>         <td>             <p style='color:#3d4d5a; font-family:"Calibri","Verdana","Arial","Helvetica"; font-size:12pt;'>                 This email has been checked for viruses by AVG antivirus software.                 <br><a href="https://www.avg.com/internet-security">www.avg.com</a>             </p>         </td>     </tr> </table> <br /> <a href="#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2" width="1" height="1"> </a></div></body></html>

    Friday, February 15, 2019 4:09 PM
  • First image refers by cid:

    src="cid:image002.jpg@01D4C54F.EF900B70"

    The second one refers by the http link:

    src="https://static.avast.com/emails/avg-mail-stamp.png"

    Most importantly, you should not be concatenating HTML strings, they must be merged:

     .HTMLBody = strBody & "<br><br>" & .HTMLBody & "<br><br>" & Signature
                    


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, February 15, 2019 4:39 PM
  • Hi Dmitry,

    My timing of copy & paste between attempts had me post with wrong image info. The code line that executes is this one as I'm sending body in HTML format.

    .HTMLBody = strBody.Replace(vbCrLf, "<br>") & "<br><br>" & "<p></p>" & "<img width=85 height=85 src=cid:image002.jpg@01D4C54F.EF900B70 align=left hspace=12 v:shapes=Picture_x0020_1>" & Signature
    If you could help me correct it then I can correct the others as I'm not sure I understand what is concatenated?

    Friday, February 15, 2019 5:02 PM
  •  What is the value of Signature?What is the value of strBody?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, February 15, 2019 5:14 PM
  • This in a module to create the email

    Const PR_ATTACH_MIME_TAG = "http://schemas.microsoft.com/mapi/proptag/0x370E001E"
        Const PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001E"
        Const PR_ATTACHMENT_HIDDEN = "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B"

        Public Sub EmailAsHtml(strSubj As String, strBody As String, blnDisplayEmail As Boolean, IsHtmlFormat As Boolean, Embedded As Boolean, Optional strAddr As String = "", Optional strAddrCC As String = "", Optional strAddrBCC As String = "", Optional strRecpt As String = "", Optional strAttach As String = "", Optional strSignature As String = "", Optional strEmailAccount As String = "")

    Dim oOutlook As Object, oMail As Object, oRecipient As Object, oAttach As Object, lngIndex As Long, Signature As String = Nothing Dim oFolder As Object, oNameSpace As Object, oExplore As Object, strAddress() As String = Nothing, strAddressCC() As String = Nothing, strAddressBCC() As String = Nothing, strAttachItem() As String = Nothing, i As Integer = Nothing Try oNameSpace = oOutlook.GetNamespace("MAPI") oFolder = oNameSpace.GetDefaultFolder(6) If Embedded = True Then oMail = oOutlook.CreateItemFromTemplate(frmEmail.txtEmbedded.Text) '(strTempFilePath) Else oMail = oOutlook.CreateItem(0) End If If Not Dir(sigpath) Is Nothing Then Signature = GetBoiler(sigpath() & ".htm") Else Signature = Nothing End If With oMail If Len(Trim(strAddr) & vbNullString) > 0 Then strAddress = Split(strAddr, ";") For lngIndex = 0 To UBound(strAddress) oRecipient = .Recipients.Add(strAddress(lngIndex)) oRecipient.Type = 1 'olTo Next lngIndex End If If Len(Trim(strAddrCC) & vbNullString) > 0 Then strAddressCC = Split(strAddrCC, ";") For lngIndex = 0 To UBound(strAddressCC) oRecipient = .Recipients.Add(strAddressCC(lngIndex)) oRecipient.Type = 2 'olCC Next lngIndex End If If Len(Trim(strAddrBCC) & vbNullString) > 0 Then strAddressBCC = Split(strAddrBCC, ";") For lngIndex = 0 To UBound(strAddressBCC) oRecipient = .Recipients.Add(strAddressBCC(lngIndex)) oRecipient.Type = 3 'olBCC Next lngIndex End If If Not String.IsNullOrEmpty(strAttach) Then strAttachItem = Split(strAttach, ";") If Not strAttachItem Is Nothing Then If IsArray(strAttachItem) Then For i = LBound(strAttachItem) To UBound(strAttachItem) oAttach = .Attachments.Add(strAttachItem(i)) Next i Else If Len(strAttach) > 0 Then oAttach = .Attachments.Add(strAttachItem) End If End If Else If Len(strAttach) > 0 Then oAttach = .Attachments.Add(strAttachItem) End If End If End If oAttach = .Attachments.Add(sigpath() & "_files\image001.jpg") .Subject = strSubj If IsHtmlFormat And Embedded = True Then .HTMLBody = strBody & "<br><br>" & .HTMLBody & "<br><br>" & Signature ElseIf IsHtmlFormat = False And Embedded = True Then .HTMLBody = WebUtility.HtmlEncode(strBody) & "<br><br>" & WebUtility.HtmlEncode(.HTMLBody) & "<br><br>" & Signature ElseIf IsHtmlFormat Then oAttach.PropertyAccessor.SetProperty(PR_ATTACH_MIME_TAG, "image/jpg") oAttach.PropertyAccessor.SetProperty(PR_ATTACH_CONTENT_ID, "image001.jpg@01D4C54F.EF900B70") oAttach.PropertyAccessor.SetProperty(PR_ATTACHMENT_HIDDEN, True) .HTMLBody = strBody.Replace(vbCrLf, "<br>") & "<br><br>" & "<p></p>" & "<img width=85 height=85 src=cid:image001.jpg@01D4C54F.EF900B70 align=left hspace=12 v:shapes=Picture_x0020_1>" & Signature Else .HTMLBody = WebUtility.HtmlEncode(strBody.Replace(vbCrLf, "<br>")) & "<br><br>" & "<p></p>" & "<img align=baseline border=0 hspace=0 src=cid:image001.jpg@01D4C54F.EF900B70 >" & Signature 'This will convert the plain text string to an Html string End If .SendUsingAccount = oNameSpace.Session.Accounts.Item(strSendAcc)

    the form to generate from has this call

    EmailAsHtml(txtSubject.Text, txtMsg, True, True, If(String.IsNullOrEmpty(txtEmbedded.Text), False, True),,, strSendTo.ToString,, txtAttach.Text, strSignat, strDefAcc)
    These are the methods to get the signature
        Public SYSversion As String = GetOS()
    
        Function sigpath() As String
            If Left$(SYSversion, 19) = "Microsoft Windows 7" Or Left$(SYSversion, 19) = "Microsoft Windows 8" Or Left$(SYSversion, 20) = "Microsoft Windows 10" Then
                Return appdata & "\Microsoft\Signatures\" & My.Settings.EmailSignature
            ElseIf Left$(SYSversion, 20) = "Microsoft Windows XP" Then
                Return "C:\Documents and Settings\" & Environ("username") &
                                "\Application Data\Microsoft\Signatures\" & My.Settings.EmailSignature
            End If
    
            Return ""
    
        End Function
    
        Function GetBoiler(ByVal sFile As String) As String
            'Dick Kusleika
            Dim fso As Object = Nothing
            Dim ts As Object = Nothing
    
            Try
                fso = CreateObject("Scripting.FileSystemObject")
                ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
    
            GetBoiler = ts.ReadAll
            fso = Nothing
            ts = Nothing
    
        End Function
    Hope you can make sense of what I'm doing here. Thanks for your help so far

    Friday, February 15, 2019 5:41 PM