Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating and deleting text file 1

Status
Not open for further replies.

Bluejay07

Programmer
Mar 9, 2007
780
CA
Hello,

I have a question about creating and deleting a text file. In my program, I am creating a text file using:
Code:
My.Computer.FileSystem.WriteAllText(pFilePath, strInfo, False)

Creating the file works great. I do not have any problem with that. Once the file is created, I do what I need to do with it, then I want to delete it. This is where I am encountering problems.

Code:
' Delete the file.
l_strFileToDelete = Application.StartupPath.Trim & "\Registration.txt"
If System.IO.File.Exists(l_strFileToDelete) = True Then
   System.IO.File.Delete(l_strFileToDelete) [red]**ERROR**[/red]
End If

At this point I receive a TargetInvocationException. Looking at the innerexception it displays
Code:
cannot access the file 'C:\\...\\Registration.txt' because it is being used by another process."

I don't know why the path has double slashes. It seems like the writing of the file is keeping it open.

What would be the best way to delete the file?

Thanks
 
I can't help with WriteAllText, but the proper .Net way of writing is to use Streams. Here is an example using a StreamWriter.

Code:
    Private Sub WriteToTextFile(ByVal FullPath As String, ByVal Text As String, ByVal Append As Boolean)
        Dim sw As IO.StreamWriter
        sw = New IO.StreamWriter(FullPath, Append)

        sw.Write(Text)

        sw.Close()
    End Sub

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Hello Sorwen,

Thank you again for your reply.
I have used the above code and it does work, however, I am still receiving the same error when I try to delete the file.

The delete function does work if I shut down the program and restart, although it does not work when the file is newly created. I'm assuming something is still keeping the file open and active.

While the program is running, if I try to physically delete the file by navigating to the folder, Windows gives the message "The action can't be completed becasue the file is open in another program. Close the file and try again."

I'm assuming something is still keeping the file open and active not allowing the file to be deleted physically or through the program.

Here's a bit more information on what I'm doing:
As per my last thread of sending an email, I am creating a text file to be sent as an attachment (which does work) then trying to immediately delete the file so it doesn't remain on the users computer.

Any other suggestions?
 

Are you disposing and setting to Nothing the objects used to send the email?

Are you disposing and setting to Nothing the objects used to write the text file?

Are you closing the text file after writing to it?



I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson

Arrrr, mateys! Ye needs ta be preparin' yerselves fer Talk Like a Pirate Day!
 
Hi Jebenson,

Thanks for the reply.
I could use more of your help. I'm assuming that is the issue since I cannot delete the file.

I am using the code provided by Sorwen from my last thread as well as this thread, with a few exceptions, such as handling the use or non use of ServerSMTP.EnableSsl and the addition of formulating the text for the text file.

Here is some code sections
Code:
   Private Sub SendMailTest(Optional ByVal pEnableSSL As Boolean = False)
      Try
         Dim SendMail As System.Net.Mail.MailMessage

         ServerSMTP = New System.Net.Mail.SmtpClient("smtp.live.com", 587)
         ServerSMTP.UseDefaultCredentials = True
         If pEnableSSL Then
            ServerSMTP.EnableSsl = True
         End If
         ServerSMTP.Credentials = New System.Net.NetworkCredential("test@hotmail.com", "TestPwd") 'Must be the same email address and password as used by the from email address.


         SendMail = New System.Net.Mail.MailMessage("test@hotmail.com", "test@test.com")
         SendMail.Subject = "test"

         Delete_TextFile()   'Ensure file does not exist.
         Write_ToFile(Application.StartupPath.Trim & "\Registration.txt")
         SendMail.Attachments.Add(New System.Net.Mail.Attachment(Application.StartupPath.Trim & "\Registration.txt"))

         SendMail.Body = "This is a test."

         ServerSMTP.SendAsync(SendMail, Me)
      Catch ex As Exception
         Dim msg As String = ex.Message

         If ex.InnerException IsNot Nothing Then
            msg &= ". " & ex.InnerException.Message
         End If

         MessageBox.Show("An exception occurred with the message:" & Environment.NewLine & msg)
      End Try
   End Sub
Code:
   Private Sub ServerSMTP_SendCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs) Handles ServerSMTP.SendCompleted

      If e.Error IsNot Nothing Then
         Dim msg As String = e.Error.Message

         m_intTries = m_intTries + 1

         If e.Error.InnerException IsNot Nothing Then
            msg &= ". " & e.Error.InnerException.Message
         End If

         If m_intTries = 2 Then     '// Avoid endless loops.
            MessageBox.Show("Send mail attempt failed with the message:" & Environment.NewLine & msg)
         Else
            If msg.Trim = "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.0 Must issue a STARTTLS command first" Then
               SendMailTest(True)
            Else
               MessageBox.Show("Send mail attempt failed with the message:" & Environment.NewLine & msg)
            End If
         End If
      Else
         MessageBox.Show("Mail Sent")

         '// Let the user know that the email was sent off successfully.
         MsgBox("Your registration information has been emailed." & Environment.NewLine & _
            "You will be contacted as soon as possible to complete the registration process.", _
             MsgBoxStyle.OkOnly, "Thank You")
      End If

      Delete_TextFile()

   End Sub

The WriteToTextFile is the exact same as above, I just provide the path and the text.
Code:
   Private Sub Delete_TextFile()
      '// Delete the registration file.

      Dim l_strFileToDelete As String

      l_strFileToDelete = Application.StartupPath.Trim & "\Registration.txt"
      If System.IO.File.Exists(l_strFileToDelete) = True Then
         'System.IO.File.Delete(l_strFileToDelete)
         My.Computer.FileSystem.DeleteFile(l_strFileToDelete)
      End If
   End Sub

What and where should be set to nothing?
 
Using it the way you are is running into a couple problem I've never encountered before because I don't delete the attachment and my write process takes longer. You have several things that could and will go wrong. First, the file may not be written by the time you try to attach it. Second, the file could be locked by the MailMessage so you can't delete it.

Which is what is happening when you try to delete it and get the error. I'm not really sure how to fix the situation. You have to find when the serverSMTP is actually through with SendMail. If you try to do anything with the attachment before or try to dispose the object yourself you are going to get an error. I'll let you know if I come up with anything.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Some changes were a little more necessary than others. I tried to document the ones that were.

Code:
    Friend WithEvents ServerSMTP As System.Net.Mail.SmtpClient

    Private Sub Write_ToFile(ByVal FullPath As String, ByVal Text As String, ByVal Append As Boolean)
        Dim sw As IO.StreamWriter
        sw = New IO.StreamWriter(FullPath, Append)

        sw.Write(Text)

        sw.Close()
        sw.Dispose()
        sw = Nothing
    End Sub

    Private Sub SendMailTest(Optional ByVal pEnableSSL As Boolean = False)
        'Has to be done out side of any try because FileCheck could throw
        'an exception that has to be ignored.
        Delete_TextFile()   'Ensure file does not exist.

        Write_ToFile(Application.StartupPath.Trim & "\Registration.txt", "", False)
        Do Until FileCheck(Application.StartupPath.Trim & "\Registration.txt") = True
            'This really, really, really, needs another check to prevent an infinite loop.
        Loop

        Try
            Dim SendMail As System.Net.Mail.MailMessage

            'Server Info
            ServerSMTP = New System.Net.Mail.SmtpClient("smtp.live.com", 587)
            ServerSMTP.UseDefaultCredentials = True
            ServerSMTP.EnableSsl = pEnableSSL
            ServerSMTP.Credentials = New System.Net.NetworkCredential("@hotmail.com", "password") 'Must be the same email address and password as used by the from email address.

            'Message
            SendMail = New System.Net.Mail.MailMessage("@hotmail.com", "test@test.com")
            SendMail.Subject = "test"
            SendMail.Body = "This is a test." 'Didn't have to move
            SendMail.Attachments.Add(New System.Net.Mail.Attachment(Application.StartupPath.Trim & "\Registration.txt"))

            'Send
            ServerSMTP.SendAsync(SendMail, SendMail) 'turns out that any object can be sent a string or in this instance I decided to send the MailMessage being sent.
        Catch ex As Exception
            Dim msg As String = ex.Message

            If ex.InnerException IsNot Nothing Then
                msg &= ". " & ex.InnerException.Message
            End If

            MessageBox.Show("An exception occurred with the message:" & Environment.NewLine & msg)
        End Try
    End Sub

    Dim m_intTries As Integer

    Private Sub ServerSMTP_SendCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs) Handles ServerSMTP.SendCompleted
        If e.Error IsNot Nothing Then
            'After looking into what information comes in this particular event argument it is
            'more proper to use the SmtpException.
            Dim ServerResponce As System.Net.Mail.SmtpException = CType(e.Error, System.Net.Mail.SmtpException)
            Dim msg As String = ServerResponce.Message

            m_intTries = m_intTries + 1

            If ServerResponce.InnerException IsNot Nothing Then
                msg &= ". " & ServerResponce.InnerException.Message
            End If

            If m_intTries = 2 Then     '// Avoid endless loops.
                MessageBox.Show("Send mail attempt failed with the message:" & Environment.NewLine & msg)
            Else
                'Check for SMTP Code rather than the string
                If ServerResponce.StatusCode = Net.Mail.SmtpStatusCode.MustIssueStartTlsFirst Then
                    SendMailTest(True)
                Else
                    MessageBox.Show("Send mail attempt failed with the message:" & Environment.NewLine & msg)
                End If
            End If
        Else
            MessageBox.Show("Mail Sent")

            '// Let the user know that the email was sent off successfully.
            MsgBox("Your registration information has been emailed." & Environment.NewLine & _
               "You will be contacted as soon as possible to complete the registration process.", _
                MsgBoxStyle.OkOnly, "Thank You")
        End If

        'This seems to be the only way to safely dispose the object so we can delete the attachments used.
        CType(e.UserState, System.Net.Mail.MailMessage).Dispose()

        'Now try deleting
        Delete_TextFile()

    End Sub

    Private Sub Delete_TextFile()
        '// Delete the registration file.

        Dim l_strFileToDelete As String

        l_strFileToDelete = Application.StartupPath.Trim & "\Registration.txt"

        If FileCheck(l_strFileToDelete) = True Then
            System.IO.File.Delete(l_strFileToDelete)
            'My.Computer.FileSystem.DeleteFile(l_strFileToDelete)
        End If
    End Sub

    Private Function FileCheck(ByVal FullPath As String) As Boolean
        Try
            Return IO.File.Exists(FullPath)
        Catch ex As Exception
            Return False
        End Try
    End Function

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Wow, thanks Sorwen.

Unfortunately, I am still receiving the same error (specifically when SendMailTest is called a second time from ServerSMTP_SendCompleted).

As per your suggestion, perhaps the first attempt is still actively using the file and hasn't released it yet.

I appreciated all of your help. Perhaps the way I am creating and deleting the file almost at the same time isn't possible.
Do you have any other suggestions?
 
Hmmm, I'm not really sure as those changes finally made it work for me so I can't say why it isn't working for you. Are you 100% sure it is the delete? Attempting to write to the file again or a second attempt at sending the file too fast would cause the error as well. Try breaking on various parts of the code and be 100% it is the delete.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
I receive the error everytime the delete is called after the file has been created. I haven't had the error occur anywhere else as of yet.
 
I tired it again and now it is failing with mine. I guess between changing stuff the resend attempt now fails. If you let it run through without its resend attempt it works fine. I'm not sure what I changed between the two, but the last code I gave you is has everything correct so it comes down possibly looking at another way to attempt to resend. Which also reminds me to bring up the point you shouldn't recreate the attachment just to try sending it again. If you resent you should be skipping the delete/create part.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Hi Sorwen,

You've got to love it when something works and the next test fails and you can't remember what changed between the two tests. I've been caught a couple of times like that.

Thank you for all of your effort and feedback you have provided. You do have a point of trying to reuse the file. I will keep trying variations to see if anything makes a difference.

Overall, you have helped me to maximize my coding efforts. Thank you.
 
You are welcome. I hope you can figure something out. It has been good for me too as I've made a few changes to the way I email thanks to the new things I had to learn trying to work out your situation. :)

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top