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));
}
}
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
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 :)
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.
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);
}
}
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.
}
}