Jump to content

how to send an email with an attachment in exchange


kor
 Share

Recommended Posts

I've already searched and everyone else is using the code that starts up outlook and what not. That is not they way I want to do it. My code below already works and it sends an email without any user interaction. what I want to do is add an attachment. The other method people use is to add the .attachment.add("file"), but I'm not sure how to integrate it into my existing code.

#include <INet.au3>

$s_SmtpServer="MYSMTPSERVER"
$s_FromName="Test Name"
$s_FromAddress="noreply@mail.org"
$s_ToAddress="account@mail.org"
$s_Subject="Errors have been detected"
Dim $as_Body[1]
$as_Body[0]="One or more accounts have errors"
$s_helo="HELO"
$b_trace=-1

$Response = _INetSmtpMail ( $s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress ,$s_Subject ,$as_Body, $s_helo, $b_trace)

$err = @error
If $Response = 1 Then
    MsgBox(0, "Success!", "Mail sent")
Else
    MsgBox(0, "Error!", "Mail failed with error code " & $err)
EndIf
Edited by kor
Link to comment
Share on other sites

I tried this code but now the emails aren't getting sent. My previous code did not need a username and password so I'm unsure what I need to be using as a user & password with the new code.

;
;##################################
; Include
;##################################
#Include<file.au3>
;##################################
; Variables
;##################################
$SmtpServer = "IP"             ; address for the smtp-server to use - REQUIRED
$FromName = "Test"     ; name from who the email was sent
$FromAddress = "mail@mail.org"      ; address from where the mail should come
$ToAddress = "mail1@mail.org"            ; destination address of the email - REQUIRED
$Subject = "Error have been detected"   ; subject from the email - can be anything you want it to be
$Body = ""                              ; the messagebody from the mail - can be left blank but then you get a blank mail
$AttachFiles = "C:\Users\test\Desktop\test.xls"                       ; the file(s) you want to attach seperated with a ; (Semicolon) - leave blank if not needed
$CcAddress = ""       ; address for cc - leave blank if not needed
$BccAddress = ""     ; address for bcc - leave blank if not needed
$Importance = "Normal"                  ; Send message priority: "High", "Normal", "Low"
$Username = "????"                    ; username for the account used from where the mail gets sent - REQUIRED
$Password = "????"                  ; password for the account used from where the mail gets sent - REQUIRED
$IPPort = 25                            ; port used for sending the mail
$ssl = 0                                ; enables/disables secure socket layer sending - put to 1 if using httpS
;~ $IPPort=465                          ; GMAIL port used for sending the mail
;~ $ssl=1                               ; GMAILenables/disables secure socket layer sending - put to 1 if using httpS

;##################################
; Script
;##################################
Global $oMyRet[2]
Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")
$rc = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)
If @error Then
    MsgBox(0, "Error sending message", "Error code:" & @error & "  Description:" & $rc)
EndIf
;
; The UDF
Func _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject = "", $as_Body = "", $s_AttachFiles = "", $s_CcAddress = "", $s_BccAddress = "", $s_Importance="Normal", $s_Username = "", $s_Password = "", $IPPort = 25, $ssl = 0)
    Local $objEmail = ObjCreate("CDO.Message")
    $objEmail.From = '"' & $s_FromName & '" <' & $s_FromAddress & '>'
    $objEmail.To = $s_ToAddress
    Local $i_Error = 0
    Local $i_Error_desciption = ""
    If $s_CcAddress <> "" Then $objEmail.Cc = $s_CcAddress
    If $s_BccAddress <> "" Then $objEmail.Bcc = $s_BccAddress
    $objEmail.Subject = $s_Subject
    If StringInStr($as_Body, "<") And StringInStr($as_Body, ">") Then
        $objEmail.HTMLBody = $as_Body
    Else
        $objEmail.Textbody = $as_Body & @CRLF
    EndIf
    If $s_AttachFiles <> "" Then
        Local $S_Files2Attach = StringSplit($s_AttachFiles, ";")
        For $x = 1 To $S_Files2Attach[0]
            $S_Files2Attach[$x] = _PathFull($S_Files2Attach[$x])
;~          ConsoleWrite('@@ Debug : $S_Files2Attach[$x] = ' & $S_Files2Attach[$x] & @LF & '>Error code: ' & @error & @LF) ;### Debug Console
            If FileExists($S_Files2Attach[$x]) Then
                ConsoleWrite('+> File attachment added: ' & $S_Files2Attach[$x] & @LF)
                $objEmail.AddAttachment($S_Files2Attach[$x])
            Else
                ConsoleWrite('!> File not found to attach: ' & $S_Files2Attach[$x] & @LF)
                SetError(1)
                Return 0
            EndIf
        Next
    EndIf
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = $s_SmtpServer
    If Number($IPPort) = 0 then $IPPort = 25
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = $IPPort
    ;Authenticated SMTP
    If $s_Username <> "" Then
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = $s_Username
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = $s_Password
    EndIf
    If $ssl Then
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
    EndIf
    ;Update settings
    $objEmail.Configuration.Fields.Update
    ; Set Email Importance
    Switch $s_Importance
        Case "High"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "High"
        Case "Normal"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Normal"
        Case "Low"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Low"
    EndSwitch
    $objEmail.Fields.Update
    ; Sent the Message
    $objEmail.Send
    If @error Then
        SetError(2)
        Return $oMyRet[1]
    EndIf
    $objEmail=""
EndFunc   ;==>_INetSmtpMailCom
;
;
; Com Error Handler
Func MyErrFunc()
    $HexNumber = Hex($oMyError.number, 8)
    $oMyRet[0] = $HexNumber
    $oMyRet[1] = StringStripWS($oMyError.description, 3)
    ConsoleWrite("### COM Error !  Number: " & $HexNumber & "   ScriptLine: " & $oMyError.scriptline & "   Description:" & $oMyRet[1] & @LF)
    SetError(1); something to check for when this function returns
    Return
EndFunc   ;==>MyErrFunc

EDIT: I've also tried the below code however it crashes Autoit. (I am running the script on a 64bit 2008 R2 VM

#include <INet.au3>
#Include <File.au3>
#include <Array.au3>

$smtpServer = "IP"
$fromName = "test"
$fromAddress = "noreply@mail.org"
$toAddress = "test@mail.org"
$ccAddress = ""
$subject = "Errors have been detected"
$attachment = @ScriptDir & "\test.xls"
$body = ""
$smtpResponse = _INetSmtpMail2($smtpServer, $fromName, $fromAddress, $toAddress, $ccAddress, $subject, $body, $attachment)
$err = @error
If $smtpResponse = 1 Then
    MsgBox(0, "Success!", "Mail sent", 0)
Else
    MsgBox(0, "Error!", "Mail failed with error code " & $err)
EndIf

;===============================================================================
;
; Function Name:    _INetSmtpMail2()
; Description:      Added support for one file attachment and one extra mail recipient from _INetSmtpMail
; Features:         File attachment and CC recipient
; Parameter(s):     $s_SmtpServer   - SMTP server
;                   $s_FromName     - Sender's email address
;                   $s_ToAddress    - Recepient's email address
;                   $s_CCAddress    - Recepient's email address 
;                   $s_Subject      - Subject
;                   $as_Body        - Message body
;                   $s_Attachment   - Path of the attachment file 
;                   $s_helo
;                   $s_first
;                   $b_trace
; Requirement(s):   INet.au3, File.au3, Array.au3
; Return Value(s):  On Success - Returns 1
;                   On Failure - Sends error code
;
;===============================================================================
Func _INetSmtpMail2($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_CCAddress = "", $s_Subject = "", $as_Body = "", $s_Attachment = "", $s_helo = "", $s_first=-1, $b_trace = 0)
    ;Encoding attachment to base64
    If $s_Attachment = "" Then 
        Else
        Local $file = FileOpen($s_Attachment, 0)
        If $file = -1 Then
            MsgBox(48, "Error", "Unable to open file.")
            Exit
        EndIf
        $encodedFile = _Base64Encode(FileRead($file)) ; Encoding file to Base64
        FileClose($file)
        Dim $szDrive, $szDir, $szFName, $szExt
        _PathSplit($s_Attachment, $szDrive, $szDir, $szFName, $szExt)
        Local $s_fileName = $szFName & $szExt
        Local $fileSize = FileGetSize($s_Attachment)
    EndIf

    ;Variables
    Dim $szDrive, $szDir, $szFName, $szExt
    Local $boundary = "^_^" & Random(1, 32) & "^_^" ; Boundary marker for different Content Type
    Local $v_Socket
    Local $s_IPAddress
    Local $i_Count
    Local $s_Send[7]
    Local $s_ReplyCode[7];Return code from SMTP server indicating success

    If $s_SmtpServer = "" Or $s_FromAddress = "" Or $s_ToAddress = "" Or $s_FromName = "" Or StringLen($s_FromName) > 256 Then
        SetError(1)
        Return 0
    EndIf
    If $s_helo = "" Then $s_helo = @ComputerName
    If TCPStartup() = 0 Then
        SetError(2)
        Return 0
    EndIf
    StringRegExp($s_SmtpServer, "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")
    If @extended Then
        $s_IPAddress = $s_SmtpServer
    Else
        $s_IPAddress = TCPNameToIP($s_SmtpServer)
    EndIf
    If $s_IPAddress = "" Then
        TCPShutdown()
        SetError(3)
        Return 0
    EndIf
    $v_Socket = TCPConnect($s_IPAddress, 25)
    If $v_Socket = -1 Then
        TCPShutdown()
        SetError(4)
        Return (0)
    EndIf

    $s_Send[0] = "EHLO " & $s_helo & @CRLF
    $s_ReplyCode[0] = "250"

    $s_Send[1] = "MAIL FROM: <" & $s_FromAddress & ">" & @CRLF
    $s_ReplyCode[1] = "250"
    $s_Send[2] = "RCPT TO: <" & $s_ToAddress & ">" & @CRLF
    $s_ReplyCode[2] = "250"
    If $s_CCAddress = "" Then
        $s_Send[3] = @CRLF
        $s_ReplyCode[3] = "500"
    Else
        $s_Send[3] = "RCPT TO: <" & $s_CCAddress & ">" & @CRLF ; CC Recipient
        $s_ReplyCode[3] = "250"
    EndIf
    $s_Send[4] = "DATA" & @CRLF
    $s_ReplyCode[4] = "354"

    Local $aResult = _Date_Time_GetTimeZoneInformation()
    Local $bias = -$aResult[1]/60
    Local $biasH = Int($bias)
    Local $biasM = 0
    If $biasH <> $bias Then $biasM =  Abs($bias - $biasH) * 60
    $bias =  StringFormat(" (%+.2d%.2d)", $biasH, $biasM)

    $data = _
            "From: " & $s_FromName & "<" & $s_FromAddress & ">" & @CRLF & _
            "To: " & "<" & $s_ToAddress & ">" & @CRLF & _
            "Cc: " & "<" & $s_CCAddress & ">" & @CRLF & _
            "Subject: " & $s_Subject & @CRLF & _
            "Importance: " & "Normal" & @CRLF & _
            "Mime-Version: 1.0" & @CRLF & _
            "Date: " & _DateDayOfWeek(@WDAY, 1) & ", " & @MDAY & " " & _DateToMonth(@MON, 1) & " " & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & $bias & @CRLF & _
            "Content-Type: multipart/mixed;" & @CRLF & _ 
            ' boundary="' & $boundary & '"' & @CRLF & _ ; Boundary specified
            @CRLF & _
            "--" & $boundary & @CRLF & _    ; body part, first boundary "--xxxx"
            'Content-Type: text/plain;' & @CRLF & _ 
            'charset="iso-8859-1"' & @CRLF & _
            'Content-Transfer-Encoding: quoted-printable' & @CRLF & @CRLF & _
            $as_body & @CRLF
    If $s_Attachment = "" Then 
        Else
        $data =  $data & @CRLF & _
            "--" & $boundary & @CRLF & _ ; file attachment part, second boundary "--xxxx"
            'Content-Type: text/plain; name="<' & $s_fileName & '>"' & @CRLF & _ 
            'Content-Transfer-Encoding: base64' & @CRLF & _
            'Content-Disposition: attachment; filename="' & $s_fileName & '"' & @CRLF & _
            ' size=' & $fileSize & @CRLF & _
            @CRLF & _ 
            $encodedFile & @CRLF
    EndIf
    $data = $data & '--' & $boundary & '--' & @CRLF ; end of boundaries --xxxx--

    $s_Send[5] = $data

    $s_ReplyCode[5] = ""

    $s_Send[6] = @CRLF & "." & @CRLF
    $s_ReplyCode[6] = "250"

    ; open stmp session
    If _SmtpSend($v_Socket, $s_Send[0], $s_ReplyCode[0], $b_trace, "220", $s_first) Then
        SetError(50)
        Return 0
    EndIf
    ; send header
    For $i_Count = 1 To UBound($s_Send) - 2
        If _SmtpSend($v_Socket, $s_Send[$i_Count], $s_ReplyCode[$i_Count], $b_trace) Then
            SetError(50 + $i_Count)
            Return 0
        EndIf
    Next

    ; send body records (a record can be multiline : take care of a subline beginning with a dot should be ..)
    For $i_Count = 0 To UBound($as_Body) - 1
        ; correct line beginning with a dot
        If StringLeft($as_Body[$i_Count], 1) = "." Then $as_Body[$i_Count] = "." & $as_Body[$i_Count]

        If _SmtpSend($v_Socket, $as_Body[$i_Count] & @CRLF, "", $b_trace) Then
            SetError(500 + $i_Count)
            Return 0
        EndIf
    Next

    ; close the SMTP session
    $i_Count = UBound($s_Send) - 1
    If _SmtpSend($v_Socket, $s_Send[$i_Count], $s_ReplyCode[$i_Count], $b_trace) Then
        SetError(5000)
        Return 0
    EndIf

    TCPCloseSocket($v_Socket)
    TCPShutdown()
    Return 1
EndFunc     ;==>_INetSmtpMail2

Func _Base64Encode($Data, $LineBreak = 76)
    Local $Opcode = "0x5589E5FF7514535657E8410000004142434445464748494A4B4C4D4E4F505152535455565758595A6162636465666768696A6B6C6D6E6F707172737475767778797A303132333435363738392B2F005A8B5D088B7D108B4D0CE98F0000000FB633C1EE0201D68A06880731C083F901760C0FB6430125F0000000C1E8040FB63383E603C1E60409C601D68A0688470183F90176210FB6430225C0000000C1E8060FB6730183E60FC1E60209C601D68A06884702EB04C647023D83F90276100FB6730283E63F01D68A06884703EB04C647033D8D5B038D7F0483E903836DFC04750C8B45148945FC66B80D0A66AB85C90F8F69FFFFFFC607005F5E5BC9C21000"

    Local $CodeBuffer = DllStructCreate("byte[" & BinaryLen($Opcode) & "]")
    DllStructSetData($CodeBuffer, 1, $Opcode)

    $Data = Binary($Data)
    Local $Input = DllStructCreate("byte[" & BinaryLen($Data) & "]")
    DllStructSetData($Input, 1, $Data)

    $LineBreak = Floor($LineBreak / 4) * 4
    Local $OputputSize = Ceiling(BinaryLen($Data) * 4 / 3) 
    $OputputSize = $OputputSize + Ceiling($OputputSize / $LineBreak) * 2 + 4

    Local $Ouput = DllStructCreate("char[" & $OputputSize & "]")
    DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer), _
                                                    "ptr", DllStructGetPtr($Input), _
                                                    "int", BinaryLen($Data), _
                                                    "ptr", DllStructGetPtr($Ouput), _
                                                    "uint", $LineBreak)
    Return DllStructGetData($Ouput, 1)
EndFunc     ;==>_Base64Encode

EDIT 2: I've noticed with this second piece of code, if I remove the attachment and CC options just to see if the script will work at all I get the following error:

C:\Users\test\Desktop\hjhjhjhjhj.au3 (155) : ==> Unknown function name.:

If _SmtpSend($v_Socket, $s_Send[0], $s_ReplyCode[0], $b_trace, "220", $s_first) Then

If ^ ERROR

Edited by kor
Link to comment
Share on other sites

Exchange means Outlook right ?

Try this:

Local $olMailItem = 0
    Local $olFormatRichText = 3
    Local $olImportanceLow = 0
    Local $olImportanceNormal = 1
    Local $olImportanceHigh = 2
    Local $olByValue = 1
    Local $olFormatHTML = 2
    Local $olFormatPlain = 1
    $oOApp = ObjCreate("Outlook.Application")
    $oOMail = $oOApp.CreateItem ($olMailItem)
    $oOMail.Save
    With $oOMail
        .To = ($to)
        .Subject = $subj
        .BodyFormat = $olFormatHTML
        .Importance = $olImportanceNormal
        .HTMLBody = "some text"
        .attachments.add ("C:\test.xls")
        .Send
    EndWith
    $oOApp=0
Link to comment
Share on other sites

I've already searched and everyone else is using the code that starts up outlook and what not. That is not they way I want to do it.

Exchange means Outlook right ?

Try this:

You didn't seem to read the first sentence of my first post. I do not want to use the code that calls outlook. Using that code requires user interaction when actually sending the email.
Link to comment
Share on other sites

I don't have outlook installed at all on the test computer. That is why I don't want to call outlook. I dont want the script dependent on if outlook is installed or not.

EDIT: tested on a computer with outlook installed just to show you. Not using your code exactly but very similar code that does pretty much does the same thing. Error below. You must not work with outlook much.

Posted Image

code I was using to test:

Local $olMailItem     = 0
    Local $olFormatRichText = 3
    Local $olImportanceLow     = 0
    Local $olImportanceNormal= 1
    Local $olImportanceHigh     = 2
Local $olByValue = 1


$oOApp = ObjCreate("Outlook.Application")
    $oOMail = $oOApp.CreateItem($olMailItem)
    ;$oOMail.Save
    With $oOMail
    .To = ("mailadres@yahoo.com")
        .Subject = "some subject"
        .BodyFormat =  $olFormatRichText
        .Importance = $olImportanceNormal
    .Body = "the body text"
      ;Display
      .Send
    EndWith
Edited by kor
Link to comment
Share on other sites

It doesn't matter because I specifically said I don't want to use outlook in my very first sentence. I solved the issue by not trying to use AutoIt for the emailing, instead using an external program called SendEmail.exe. I lightweight smtp mailer that I just run from within Autoit. Solved.

Link to comment
Share on other sites

  • Developers

It doesn't matter because I specifically said I don't want to use outlook in my very first sentence. I solved the issue by not trying to use AutoIt for the emailing, instead using an external program called SendEmail.exe. I lightweight smtp mailer that I just run from within Autoit. Solved.

It should also work fine with the _INetSmtpMail() UDF which uses standard CDO. :) Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • 1 month later...

But _INetSmtpMail can't add an attachment, can it?

I'm trying to do something similar. I inherited a routine from a long gone predecessor that sends mail via a VB script in Excel. Worked except for the stupid "a program is trying to send email..." thing, so I wrapped an Autoit script around it to click in all the right places. Problem solved, at the time, but the VB script is broken in Win7.

I need a way to send an email, with or without actually using Outlook, but including the Excel file attachment.

Link to comment
Share on other sites

  • Developers

But _INetSmtpMail can't add an attachment, can it?

Yea, I meant the _INetSmtpMailCom() which can be found in the Examples forum.

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • 3 years later...

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...