0

Below is the email code I am using to send an email with attached document, but when I try to delete the files it is showing that the files are in use. Any help will be appreciated.

Sub email()
    Dim Smtp_Server As New SmtpClient
    Dim e_mail As New MailMessage()
    Dim body As String
    Dim address As String
    Dim address2 As String
    Dim address3 As String
    Dim fileReader As System.IO.StreamReader

    fileReader = My.Computer.FileSystem.OpenTextFileReader("C:\VB Test\location.txt")
    Dim Pathstore As String
    Pathstore = fileReader.ReadLine()

    'email address
    Dim lines() As String = System.IO.File.ReadAllLines("C:\VB Test\stores.txt")

    For Each line As String In Filter(lines, Pathstore)
        Dim fields() As String = line.Split(",")
        address = fields(4)
        address2 = fields(2)
        address3 = fields(6)
    Next

    Dim fileReader2 As System.IO.StreamReader
    fileReader2 = My.Computer.FileSystem.OpenTextFileReader("C:\VB Test\rmmsiul.dll")
    Dim Pathcode As String
    Pathcode = fileReader2.ReadLine()
    fileReader2.Close()

    body = "Here are the manual reciepts I created today." + vbNewLine + vbNewLine + vbNewLine & "Thank you," + vbNewLine + Pathstore


    Smtp_Server.UseDefaultCredentials = False
    Smtp_Server.Credentials = New Net.NetworkCredential("Do-Not-Reply@suncommobile.com", Pathcode)
    Smtp_Server.Port = 587
    Smtp_Server.EnableSsl = True
    Smtp_Server.Host = "smtp.office365.com"

    e_mail = New MailMessage()
    e_mail.From = New MailAddress("Do-Not-Reply@suncommobile.com")
    e_mail.CC.Add(address)
    e_mail.CC.Add(address2)
    e_mail.CC.Add(address3)
    e_mail.Subject = Pathstore + " Manual reciepts"
    e_mail.IsBodyHtml = False
    e_mail.Body = body
    Dim filepath As String
    For Each filepath In Directory.GetFiles("C:\VB Test\Receipts")
        Dim Attach As New Net.Mail.Attachment(filepath)
        e_mail.Attachments.Add(Attach)
        Kill(filepath)
    Next
    Smtp_Server.Send(e_mail)

    MsgBox("E-mail Sent.")
    Module1.filedelete()

End Sub

'changed part of the code to the following, but getting error when sending email.

    For Each filepath As String In Directory.GetFiles("C:\VB Test\Receipts")
        Using reader As New StreamReader(filepath)
            Dim a As New Net.Mail.Attachment(reader.BaseStream, filepath)
            e_mail.Attachments.Add(a)
        End Using
    Next
    Smtp_Server.Send(e_mail)
Tim R
  • 3
  • 2
  • 1
    If you load the files into [MemoryStream](https://msdn.microsoft.com/en-us/library/system.io.memorystream(v=vs.110).aspx)s and attach the MemoryStreams instead of the files then you should be able to delete the files. It might be more sensible to move the files to another directory for deletion at some later time because if there is a problem sending the email then all is lost. – Andrew Morton Jul 21 '16 at 20:34
  • The reason they won't delete is your MailMessage (e_mail) still has a handle pointing at the files. @AndrewMorton is right that you may want to copy those files elsewhere if something goes wrong. Or add each filepath to a list or array for later deletion after the email was sent. – Jimmy Smith Jul 21 '16 at 20:38
  • is there a way to close the handle or can you show me a better way to code it? – Tim R Jul 21 '16 at 21:12
  • @JimmySmith is there a way to close the handle or can you show me a better way to code it? – Tim R Jul 21 '16 at 21:18
  • @AndrewMorton I tried to research how to load them into memory streams, can you please assist with code? – Tim R Jul 21 '16 at 21:59
  • @TimR [how to load a file into memory stream](http://stackoverflow.com/a/6214032/1115360) – Andrew Morton Jul 22 '16 at 08:39

1 Answers1

1
Public Sub email()
    Dim Pathstore As String = String.Empty
    Dim Pathcode As String = String.Empty

    With New StreamReader("C:\VB Test\location.txt")
        Pathstore = .ReadLine()
        .Dispose()
    End With

    ' Are you sure this is the correct file ?
    With New StreamReader("C:\VB Test\rmmsiul.dll")
        Pathcode = .ReadLine()
        .Dispose()
    End With

    ' Capture the list of Attachment Files here, then use it twice below
    Dim Attachments() As String = Directory.GetFiles("C:\VB Test\Receipts")

    Dim e_mail As New Net.Mail.MailMessage()
    With e_mail
        .From = New Net.Mail.MailAddress("Do-Not-Reply@suncommobile.com")
        .Subject = String.Format("{0} Manual reciepts", Pathstore)
        .Body = String.Format("Here are the manual reciepts I created today.{0}{0}{0}Thank you,{0}{1}", Environment.NewLine, Pathstore)

        ' Since I don't know what Filter() returns, this is best guess to reproduce the same outcome
        For Each line As String In Filter(File.ReadAllLines("C:\VB Test\stores.txt"), Pathstore)
            Dim fields() As String = line.Split(",")
            .CC.Clear()
            .CC.Add(fields(4))
            .CC.Add(fields(2))
            .CC.Add(fields(6))
        Next

        For Each filepath In Attachments
            .Attachments.Add(New Net.Mail.Attachment(filepath))
        Next
    End With

    With New Net.Mail.SmtpClient
        .Host = "smtp.office365.com"
        .Credentials = New Net.NetworkCredential("Do-Not-Reply@suncommobile.com", Pathcode)
        .Port = 587
        .EnableSsl = True
        .Send(e_mail)
    End With

    ' Dispose the MailMessage to release the holds on the Attachment Files
    e_mail.Dispose()

    ' Delete the Attachment Files
    For Each filepath In Attachments
        File.Delete(filepath)
    Next

    MsgBox("E-mail Sent.")
End Sub
MrGadget
  • 1,258
  • 1
  • 10
  • 19