27

I have a function thats sending messages ( a lot of them) and their attachments.

It basically loops through a directory structure and creates emails from a file structure for example

 c:\emails\message01
                \attachments
 c:\emails\message02
                \attachments

The creation of the messages takes place using .net c#, standard stuff.

After all messages are created... I have another function that runs directly afterwards that copies the message folder to another location.

Problem is - files are locked...

Note: I'm not moving the files, just copying them....

Any suggestions on how to copy locked files, using c#?

Update

I have this add attachments method

    private void AddAttachments(MailMessage mail)
    {
        string attachmentDirectoryPath = "c:\messages\message1";
        DirectoryInfo attachmentDirectory = new DirectoryInfo(attachmentDirectoryPath);
        FileInfo[] attachments = attachmentDirectory.GetFiles();
        foreach (FileInfo attachment in attachments)
        {
            mail.Attachments.Add(new Attachment(attachment.FullName));
        }
    }
JL.
  • 78,954
  • 126
  • 311
  • 459

5 Answers5

60

How are you reading the files to create the email message? They should be opened as read-only, with a FileShare set to FileShare.ReadWrite... then they shouldn't be locked. If you are using a FileStream you should also wrap your logic in the using keyword so that the resource is disposed properly.

Update:

I believe disposing the mail message itself will close resources within it and unlock the files:

using (var mail = new MailMessage())
{
    AddAttachments(mail);
}
// File copy code should work here
Community
  • 1
  • 1
John Rasch
  • 62,489
  • 19
  • 106
  • 139
22

hate answering my own post, but yeah for the next poor guy who has this problem here is the fix:

AFTER YOU SEND THE MESSAGE

        // Send the mail
        client.Send(message);

        //Clean up attachments
        foreach (Attachment attachment in message.Attachments)
        {
            attachment.Dispose();
        }

Dispose the attachments... clears the lock, and messages will still be sent with attachments. Dispose DOES NOT delete the files, just clears the attachments :)

JL.
  • 78,954
  • 126
  • 311
  • 459
  • 7
    John Rasch has the correct answer: You should dispose of the `MailMessage` itself (preferably by wrapping it in a `using` block). The `Dispose` method of the `MailMessage` also disposes any attachments. – LukeH Aug 18 '09 at 21:36
3

Are you closing the files after you finish reading them? If you open them for reading, but don't close them when you're done, it should keep a lock on it until the program exits and automatically closes all the files.

matthock
  • 629
  • 1
  • 4
  • 15
  • Thanks for the answer - not really opening the files, just adding them, like in the code above – JL. Aug 18 '09 at 21:00
2
    MailMessage email = new MailMessage();

    email.From = txtFrom.Text;
    email.To = txtToEmail.Text;
    email.Subject = txtMSubject.Text; 
    email.Body = txtBody.Text;

    SmtpClient mailClient = new SmtpClient();
    mailClient.Host = "smtp.emailAddress";
    mailClient.Port = 2525;
    mailClient.Send(email );
    email.Dispose();

    // After Disposing the email object you can call file delete

    if (filePath != "")
    {
      if (System.IO.File.Exists(filePath))
      {
        System.IO.File.Delete(filePath); 
      }
    }
dnxit
  • 7,118
  • 2
  • 30
  • 34
  • 1
    This is the correct answer and should work with ASync sending also if you pass the MailMessage object to it in the user parameters – rboy Nov 26 '17 at 22:03
0

I see this a lot when sending attachments. I normally use something like the following:

In the code that moves the files to a different location, you can use the following pattern:

Inside the loop for looping through the files

bool FileOk = false;
while (!FileOk)
{
   try
   {
      // code to move the file
      FileOk = true;
   }
   catch(Exception)
   {
      // do nothing or write some code to pause the thread for a few seconds.
   }

}
David
  • 72,686
  • 18
  • 132
  • 173
  • Don't really want to go this route, for the reason that another process like indexing service could lock the file, creating a dead link in my app, but thanks for the suggestion. – JL. Aug 18 '09 at 21:02