Jump to content

Eml file with body base64 encoded DECODER


Recommended Posts

Hello. I am trying to decode eml file body part encoded with base64.
This is the file content example:

Quote

MIME-Version: 1.0
From: "MyFriend" <my@friend.com>
To: "me and myself" <me@myself.i>
Date: 22 Jan 2022 20:19:35 +0100
Subject: testing
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

SGVsbG8gQXV0b0l0IGZvcnVtIHVzZXIuIFRoYW5rIHlvdSBmb3IgdHJ5aW5nIHRvIGhlbHAgbWUg
ZmlndXJlIHRoaXMgcHJvYmxlbSBvdXQu

and this is my code:

#include "Base64.au3"
#include <FileConstants.au3>

Global $g_EmlFile_FullPath = FileOpenDialog(Default, _
    @UserProfileDir & "\Downloads", "Eml file format (*.eml)", $FD_FILEMUSTEXIST)
If @error Then Exit

Global $sEmlBodyDecoded = EmlFileBase64BodyDecoder($g_EmlFile_FullPath)
ConsoleWrite($sEmlBodyDecoded & @CRLF)

Func EmlFileBase64BodyDecoder($EmlFile_FullPath)

    Local $hFileOpen = FileOpen($EmlFile_FullPath, $FO_READ)
    If $hFileOpen = -1 Then Return SetError(1, 0, -1)
    Local $sFileRead = FileRead($hFileOpen)
    FileClose($hFileOpen)

    Local $HeaderAndBodySeparatorString = @CRLF & @CRLF
    Local $StartPos = StringInStr($sFileRead, $HeaderAndBodySeparatorString)
    $StartPos = $StartPos + StringLen($HeaderAndBodySeparatorString) - 1

    Local $sEmlBody = StringTrimLeft($sFileRead, $StartPos + StringLen($HeaderAndBodySeparatorString) - 1)

    if not StringIsASCII ($sEmlBody) then Return SetError(2, 0, -1)

    Return _Base64Decode($sEmlBody)
EndFunc

And i can't decode it. When I try the base64 in some online converter then it works but can't achieve it in AutoIt. What is wrong?

Link to post
Share on other sites

TIP:
 

Quote

SGVsbG8gQXV0b0l0IGZvcnVtIHVzZXIuIFRoYW5rIHlvdSBmb3IgdHJ5aW5nIHRvIGhlbHAgbWUg
ZmlndXJlIHRoaXMgcHJvYmxlbSBvdXQu

Combine strings:

Quote

SGVsbG8gQXV0b0l0IGZvcnVtIHVzZXIuIFRoYW5rIHlvdSBmb3IgdHJ5aW5nIHRvIGhlbHAgbWUgZmlndXJlIHRoaXMgcHJvYmxlbSBvdXQu

 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 for other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2022-03-07

Link to post
Share on other sites

Take a look on this my old script:

;~ https://www.autoitscript.com/forum/topic/174414-determining-size-of-attachment-from-eml-files-multiple-attachmentshashedcoded/
;~ https://msdn.microsoft.com/en-us/library/ms526130(v=exchg.10).aspx
;~ https://msdn.microsoft.com/en-us/library/ms526453(v=exchg.10).aspx

;~ Interfaces
;~ https://msdn.microsoft.com/en-us/library/ms877953(v=exchg.65).aspx

#include "array.au3"
Global Const $sCLASSID_IMessage = "{CD000001-8B95-11D1-82DB-00C04FB1625D}"

_Example()
Func _Example($vParam = Default)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    Local Static $oMessage = Null
    If $vParam = Default Then
        _EML_MessageCreateObj($oMessage)
        _EML_LoadEml($oMessage, 'EMAIL2.eml')
        MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONINFORMATION, 'Time1', _EML_Message_TimeSent($oMessage))
        $oRecipients_col = $oMessage.Recipients
        For $oRecipient_enum In $oRecipients_col
            ConsoleWrite($oRecipient_enum.Name & @CRLF)
            ConsoleWrite($oRecipient_enum.Adress & @CRLF)
        Next
    Else
        MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONINFORMATION, 'Time2', _EML_Message_TimeSent($oMessage))
    EndIf
EndFunc   ;==>_Example



_Example_1()
Func _Example_1()
    Local $sEMLPath = "EMAIL.eml"
    $sAttachment = "IDAutomationHC39M.ttf"

    $iSize = GetAttachmentSize($sEMLPath, $sAttachment)
    Local $aAttachments = GetAttachmentList($sEMLPath)
    _ArrayDisplay($aAttachments)


    If @error Then
        $sErrDesc = "You can't use this method because "
        Switch @error
            Case 1
                $sErrDesc &= "CDO sucks for you."
            Case 2
                $sErrDesc &= "getting stream failed."
            Case 3
                $sErrDesc &= "loading EML failed."
            Case 4
                $sErrDesc &= "of some dumb error."
            Case 5
                $sErrDesc = "No such attachment exists."
        EndSwitch
        MsgBox(4096, "Error", $sErrDesc & @CRLF)
    Else
        MsgBox(4096, "...", 'Attachment named "' & $sAttachment & '" is ' & $iSize & " bytes big" & @CRLF)
    EndIf

EndFunc   ;==>_Example_1



Func GetAttachmentSize($sEMLPath, $sAttachmentName)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    Local $oMessage = ObjCreate($sCLASSID_IMessage) ; with all the downsides
;~  https://msdn.microsoft.com/en-us/library/ms526453(v=exchg.10).aspx
    If @error Then Return SetError(1, 0, -1)
;~  ObjName_FlagsValue($oMessage)
;~  MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONINFORMATION, '', 11)

    _EML_LoadEml($oMessage, $sEMLPath)
    If @error Then Return SetError(3, 0, -1)

    MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONINFORMATION, '$oMessage.TimeSent', $oMessage.TimeSent)
    Local $iSize
;~  https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2007/aa579703(v=exchg.80)
    For $oAttachment In $oMessage.Attachments
        If $oAttachment.FileName = $sAttachmentName Then
            $iSize = $oAttachment.GetDecodedContentStream().Size
        EndIf
        If @error Then Return SetError(4, 0, -1)
        If $iSize Then Return $iSize
    Next

    Return SetError(5, 0, -1)
EndFunc   ;==>GetAttachmentSize

Func SaveAttachment($sEMLPath, $sAttachmentName)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    Local $oMessage = ObjCreate($sCLASSID_IMessage) ; with all the downsides
    If @error Then Return SetError(1, 0, -1)

    Local $oMessageStream = $oMessage.GetStream()
    If @error Then Return SetError(2, 0, -1)

    $oMessageStream.LoadFromFile($sEMLPath)
    If @error Then Return SetError(3, 0, -1)

    $oMessageStream.Flush() ; this is essential

    Local $iSize
    For $oAttachment In $oMessage.Attachments
        If $oAttachment.FileName = $sAttachmentName Then $oAttachment.SaveToFile(@ScriptDir & "\" & $sAttachmentName)
        If @error Then
            Return SetError(4, 0, -1)
        Else
            Return SetError(0, 0, 1)
        EndIf
    Next

    Return SetError(5, 0, -1)
EndFunc   ;==>SaveAttachment

Func GetAttachmentList($sEMLPath)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    Local $oMessage = ObjCreate($sCLASSID_IMessage) ; with all the downsides
    If @error Then Return SetError(1, 0, -1)

    Local $oMessageStream = $oMessage.GetStream()
    If @error Then Return SetError(2, 0, -1)


    ; LoadFromFile Method (ADO)
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms677570(v=vs.85).aspx
    $oMessageStream.LoadFromFile($sEMLPath)
    If @error Then Return SetError(3, 0, -1)

    $oMessageStream.Flush() ; this is essential

    Local $sAttachments = ''
    For $oAttachment In $oMessage.Attachments
        $sAttachments &= $oAttachment.FileName & '|'
    Next
    If $sAttachments <> '' Then
        StringTrimRight($sAttachments, 1)
        Local $aAttachments = StringSplit($sAttachments, '|')
        Return SetError(0, 0, $aAttachments)
    Else
        Return SetError(4, 0, -1)
    EndIf

    Return SetError(5, 0, -1)
EndFunc   ;==>GetAttachmentList




Func _EML_Message_TimeSent(ByRef $oMessage)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")
;~ TimeSent Property (Message Object)
;~ https://msdn.microsoft.com/en-us/library/ms528105(v=exchg.10).aspx
;~  ObjName_FlagsValue($oMessage)
    Return $oMessage.TimeSent
;~  Return $oMessage.TimeLastModified
;~  Return $oMessage.Type
;~  Return $oMessage.TimeReceived
;~  Return $oMessage.GetStream
EndFunc   ;==>_EML_Message_TimeSent

Func _EML_MessageCreateObj(ByRef $oMessage)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    ; IMessage Interface
    ; https://msdn.microsoft.com/en-us/library/ms526453(v=exchg.10).aspx
    $oMessage = ObjCreate($sCLASSID_IMessage) ; with all the downsides
    If @error Then Return SetError(1, @error, -1)

    Return SetError(0, 0, 1)
EndFunc   ;==>_EML_MessageCreateObj

Func _EML_LoadEml(ByRef $oMessage, $sEMLPath)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")
    Local $oMessageStream = $oMessage.GetStream()
    If @error Then Return SetError(2, 0, -1)

    ; LoadFromFile Method (ADO)
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms677570(v=vs.85).aspx
    $oMessageStream.LoadFromFile($sEMLPath)
    If @error Then Return SetError(3, 0, -1)

    $oMessageStream.Flush() ; this is essential
;~  MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONINFORMATION, '1a', $oMessage.TimeRecevied)
;~  MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONINFORMATION, '1b', $oMessage.Importance)
EndFunc   ;==>_EML_LoadEml

#Region - DOC

#cs
    IMessage Interface - http://msdn.microsoft.com/en-us/library/ms526453(v=vs.85).aspx
    CreateMHTMLBody Method - http://msdn.microsoft.com/en-us/library/ms527024(v=vs.85).aspx
    CdoMHTMLFlags Enum - http://msdn.microsoft.com/en-us/library/ms526977(v=vs.85).aspx
    GetStream Method - http://msdn.microsoft.com/en-us/library/ms527348(v=vs.85).aspx
    SaveToFile Method - http://msdn.microsoft.com/en-us/library/ms676152(v=vs.85).aspx
    SaveOptionsEnum - http://msdn.microsoft.com/en-us/library/ms676152(v=vs.85).aspx
#ce
#EndRegion - DOC



; User's COM error function. Will be called if COM error occurs
Func _ErrFunc($oError)
    ; Do anything here.
    ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _
            @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
            @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
            @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
            @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
            @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
            @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
            @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
            @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
            @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_ErrFunc



Func ObjName_FlagsValue(ByRef $oObj)
    Local $sInfo = ''

    $sInfo &= '+>' & @TAB & 'ObjName($oObj,1) {The name of the Object} =' & @CRLF & @TAB & ObjName($oObj, $OBJ_NAME) & @CRLF

    ; HELPFILE REMARKS: Not all Objects support flags 2 to 7. Always test for @error in these cases.
    $sInfo &= '+>' & @TAB & 'ObjName($oObj,2) {Description string of the Object} =' & @CRLF & @TAB & ObjName($oObj, $OBJ_STRING)
    If @error Then $sInfo &= '@error = ' & @error
    $sInfo &= @CRLF & @CRLF

    $sInfo &= '+>' & @TAB & 'ObjName($oObj,3) {The ProgID of the Object} =' & @CRLF & @TAB & ObjName($oObj, $OBJ_PROGID)
    If @error Then $sInfo &= '@error = ' & @error
    $sInfo &= @CRLF & @CRLF

    $sInfo &= '+>' & @TAB & 'ObjName($oObj,4) {The file that is associated with the object in the Registry} =' & @CRLF & @TAB & ObjName($oObj, $OBJ_FILE)
    If @error Then $sInfo &= '@error = ' & @error
    $sInfo &= @CRLF & @CRLF

    $sInfo &= '+>' & @TAB & 'ObjName($oObj,5) {Module name in which the object runs (WIN XP And above). Marshaller for non-inproc objects.} =' & @CRLF & @TAB & ObjName($oObj, $OBJ_MODULE)
    If @error Then $sInfo &= '@error = ' & @error
    $sInfo &= @CRLF & @CRLF

    $sInfo &= '+>' & @TAB & 'ObjName($oObj,6) {CLSID of the object''s coclass} =' & @CRLF & @TAB & ObjName($oObj, $OBJ_CLSID)
    If @error Then $sInfo &= '@error = ' & @error
    $sInfo &= @CRLF & @CRLF

    $sInfo &= '+>' & @TAB & 'ObjName($oObj,7) {IID of the object''s interface} =' & @CRLF & @TAB & ObjName($oObj, $OBJ_IID)
    If @error Then $sInfo &= '@error = ' & @error
    $sInfo &= @CRLF & @CRLF

    MsgBox($MB_SYSTEMMODAL, "ObjName:", $sInfo)
EndFunc   ;==>ObjName_FlagsValue

and:

    IMessage Interface - https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2007/aa579703(v=exchg.80)
    IMessage Interface - http://msdn.microsoft.com/en-us/library/ms526453(v=vs.85).aspx

 

https://docs.microsoft.com/en-us/previous-versions/exchange-server/exchange-10/ms527537(v=exchg.10)

 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 for other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2022-03-07

Link to post
Share on other sites
2 hours ago, maniootek said:

And i can't decode it. When I try the base64 in some online converter then it works but can't achieve it in AutoIt. What is wrong?

Most Base64 decode functions return a binary data type.  Therefore, you need to convert the binary to string (if the result is supposed to be a string).  However, the UDF that you are using does not.

#include <base64.au3>

Const $BASE64_DATA = "SGVsbG8gQXV0b0l0IGZvcnVtIHVzZXIuIFRoYW5rIHlvdSBmb3IgdHJ5aW5nIHRvIGhlbHAgbWUg" & @CRLF & _
                     "ZmlndXJlIHRoaXMgcHJvYmxlbSBvdXQu"

;Show output
ConsoleWrite("Base64 Value = " & _base64decode($BASE64_DATA) & @CRLF)
ConsoleWrite("Base64 Value = " & BinaryToString(_base64decode($BASE64_DATA)) & @CRLF)

Output

Base64 Value = Hello AutoIt forum user. Thank you for trying to help me figure this problem out.
Base64 Value = Hello AutoIt forum user. Thank you for trying to help me figure this problem out.

 

Edited by TheXman
Link to post
Share on other sites

As you can see in the previous post, the Base64Decode function successfully decodes the base64 string that is in your email body.  Since your function, that decodes the email body, is not working correctly, I would suggest that you look at what you are supplying to the Base64Decode() function to see if it is what you think it is.  In other words, look at what's in $sEmlBody.

Link to post
Share on other sites

If you run Outlook you could use the _OL_Example_Import_EML.au3 script that comes with my OutlookEX UDF to import EML files.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

 

@TheXman I tried your way before I posted my problem here. This wasn't so simple. Of course I checked the string I extracted from eml file and it was correct (I tried with online base64 decoder) but I guess there was some problem with utf-8/ansi encoding during file read.

 

Anyway, I checked @mLipok code and I changed it to read body part.

I achieve this working code which read body of eml file no matter if it is base64 encoded or not.


 

#include <FileConstants.au3>

;https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2007/aa579703(v=exchg.80)

Global Const $sCLASSID_IMessage = "{CD000001-8B95-11D1-82DB-00C04FB1625D}"

Global $g_EmlFile_FullPath = FileOpenDialog(Default, _
    @UserProfileDir & "\Downloads", "Eml file format (*.eml)", $FD_FILEMUSTEXIST)
If @error Then Exit

Global $sEmlBodyDecoded = EmlFileHtmlBody($g_EmlFile_FullPath)
ConsoleWrite($sEmlBodyDecoded & @CRLF)

Func EmlFileHtmlBody($EmlFile_FullPath)
    Local Static $oMessage = Null
    _EML_MessageCreateObj($oMessage)
    _EML_LoadEml($oMessage, $EmlFile_FullPath)
    Return $oMessage.HTMLBody
EndFunc

Func _EML_MessageCreateObj(ByRef $oMessage)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    $oMessage = ObjCreate($sCLASSID_IMessage) ; with all the downsides
    If @error Then Return SetError(1, @error, -1)

    Return SetError(0, 0, 1)
EndFunc   ;==>_EML_MessageCreateObj

Func _EML_LoadEml(ByRef $oMessage, $sEMLPath)
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")
    Local $oMessageStream = $oMessage.GetStream()
    If @error Then Return SetError(2, 0, -1)

    $oMessageStream.LoadFromFile($sEMLPath)
    If @error Then Return SetError(3, 0, -1)

    $oMessageStream.Flush()
EndFunc   ;==>_EML_LoadEml

; User's COM error function. Will be called if COM error occurs
Func _ErrFunc($oError)
    ; Do anything here.
    ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _
            @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
            @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
            @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
            @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
            @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
            @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
            @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
            @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
            @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_ErrFunc

Thank you guys

Edited by maniootek
Link to post
Share on other sites

Great solution!

Would you mind if I added this to my OutlookTools UDF?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

I will add a reference to this thread and give credit to you and mLipok as the authors of this code :) 

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites
1 hour ago, water said:

Would you mind if I added this to my OutlookTools UDF?

Feel free to add my code to your's UDF.

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 for other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2022-03-07

Link to post
Share on other sites

Something for you to play with:

; #FUNCTION# ====================================================================================================================
; Name...........: _OLT_EML_Get
; Description ...: Returns the content of an EML file as a serialized stream within a single ADO Stream object.
; Syntax.........: _OLT_EML_Get($sEMLPath[, $sProperty = Default])
; Parameters ....: $sEMLPath - Path to an EML mail file e.g. "C:\Local\Test.EML"
;                  $sPropery - [optional] Property to return. See Remarks (default = keyword Default)
; Return values .: Success - Sets global variable $__g_oIMessage to the ADO stream object and [optional] returns the specified property
;                  Failure - Returns 0 and sets @error:
;                  |1  - Could not create the IMessage object. @extended is set to the COM error code
;                  |2  - Could not create the ADO stream object. @extended is set to the COM error code
;                  |3  - Error accessing property $sProperty. Maybe the specified property does not exist?
; Author ........: maniootek, mLipok (in alph. order)
; Modified ......: water
; Remarks .......: The function always sets the global variable $__g_oIMessage to the ADO stream object.
;                  So you can access all properties after the function has been called.
;                  This is true even when you call the function using $sProperty to return the value of a single property.
;                  A list of available properties can be found here:
;                  iMessage: https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2007/aa579703(v=exchg.80)
;+
;                  Further information:
;                  ADO: https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/stream-object-ado?view=sql-server-ver15
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _OLT_EML_Get($sEMLPath, $sProperty = Default)
    Local Const $sCLASSID_IMessage = "{CD000001-8B95-11D1-82DB-00C04FB1625D}" ; CLSID of the IMessage interface
    Local $oADOStream
    If Not IsDeclared("__g_oIMessage") Then
        Global Static $__g_oIMessage = ObjCreate($sCLASSID_IMessage)
        If @error Then Return SetError(1, @error, 0)
    EndIf
    $oADOStream = $__g_oIMessage.GetStream() ; Return the message in serialized (wire-transport) format in a ADO stream object
    If @error Then Return SetError(2, @error, 0)
    $oADOStream.LoadFromFile($sEMLPath)
    If @error Then Return SetError(3, @error, 0)
    $oADOStream.Flush()
    If $sProperty <> Default Then
        $sResult = Execute("$__g_oIMessage." & $sProperty)
        If @error Then Return SetError(3, @error, 0)
        Return $sResult
    EndIf
EndFunc   ;==>_OLT_EML_Get

Example:

#include <OutlookTools.au3>
_OL_ErrorNotify(2)

Global $sTextBody = _OLT_EML_Get("C:\Local\Test.EML", "TextBody")
ConsoleWrite("@Error: " & @error & ", @Extended: " & @extended & @CRLF)

; Function _OLT_EML_Get returns property TextBody (1) or you directly retrieve the TextBody from the ADO stream (2)
ConsoleWrite(StringLeft($sTextBody, 80) & @CRLF) ; Example (1)
ConsoleWrite(StringLeft($__g_oIMessage.TextBody, 80) & @CRLF) ; Example (2)

 

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...