Home > OS >  IOException: 'The process cannot access the file being used"
IOException: 'The process cannot access the file being used"

Time:02-16

at this time i have this doing the moving and renaming and sending my email out with the attached file. The file that is left in the folder after the email is sent needs to be deleted but when I use the line

      if (File.Exists(@"C:\rcs\versisendemail\reports\eod.txt"))
        {
         
            File.Delete(@"C:\rcs\versisendemail\reports\eod.txt");
        }

I get the exception saying file in use. and I am not sure how to close the file in use to delete it?

full code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Mail;
using System.Runtime.InteropServices;
using System.IO;

namespace Versi_Send_Email
{

public partial class mail : Form


{
    public WindowSettings OwningWindowSettings { get; set; }
    public string CC { get; private set; }
    public string Bcc { get; private set; }
    public object filename { get; private set; }

    private static Timer _timer = new Timer();
 

    public mail()
    {
        InitializeComponent();
        _timer.Tick  = _timer_Tick;
        _timer.Interval = 5000; // 5 seconds
        _timer.Start();

    }
    void _timer_Tick(object sender, EventArgs e)
    {

        this.Close();
        if (OwningWindowSettings != null)
            OwningWindowSettings.Close();
    }



    private void sndmailbtn_Click(object sender, EventArgs e)
    {
        string fileName = ".txt";
        string sourcePath = @"C:\rcs\storage";
        string targetPath = @"C:\rcs\versisendemail\reports";
        

        string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
        string destFile = System.IO.Path.Combine(targetPath, fileName);


        // Create a new target folder.
        // If the directory already exists, this method does not create a new directory.
        System.IO.Directory.CreateDirectory(targetPath);




        // search and copy rpt files.
        if (System.IO.Directory.Exists(sourcePath))
        {
            string[] files = System.IO.Directory.GetFiles(sourcePath, "*.rpt*");

            foreach (string s in files)
            {
                
                fileName = System.IO.Path.GetFileName(s);
                destFile = System.IO.Path.Combine(targetPath, fileName);
                System.IO.File.Copy(s, destFile, true);
                
            }

            
            {
                string filename;
                string[] filePaths = 
Directory.GetFiles(@"c:\rcs\versisendemail\reports\");
                Console.WriteLine("Directory consists of "   filePaths.Length   " 
files.");
                foreach (string myfile in filePaths)
                {
                    filename = Path.ChangeExtension(myfile, ".txt");
                    System.IO.File.Move(myfile, filename);
                }


            }

            {
                DirectoryInfo d = new DirectoryInfo(@"c:\rcs\versisendemail\reports");
                FileInfo[] infos = d.GetFiles("*.txt");
                foreach (FileInfo f in infos)
                {

                    File.Move(f.FullName, Path.Combine(f.DirectoryName, "eod.txt"));
                }
               
            }

        }
        {
            INIFile inif = new INIFile(@"c:\rcs\versisendemail\mailsettings.ini");

            try
            {

                MailMessage mailMessage = new MailMessage();



                SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
                mailMessage.From = new MailAddress("[email protected]");
                mailMessage.To.Add(inif.Read("Properties", "personto"));


                mailMessage.Subject = inif.Read("Properties", "site")   " End Of Day 
Report";
                mailMessage.IsBodyHtml = true;
                mailMessage.Body = "Greetings, attached is your End-of-Day Report.<br/> 
If you have any questions or concerns about this report please contact VersiPOS Client 
Services at [email protected] or by calling us at (800) 655-7349.<br/>   <img 
src='C:\\test\\1.jpg'/>";


                System.Net.Mail.Attachment attachment;
                attachment = new 
System.Net.Mail.Attachment(@"c:\rcs\versisendemail\reports\eod.txt");
                mailMessage.Attachments.Add(attachment);


                SmtpServer.Port = 587;
                SmtpServer.Credentials = new 
System.Net.NetworkCredential("reports@xxxxx", "xxxxxxx");
                SmtpServer.EnableSsl = true;

                SmtpServer.Send(mailMessage);
                //   MessageBox.Show("mail Send");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

           
        }


        if (File.Exists(@"C:\rcs\versisendemail\reports\eod.txt"))
        {
         
            File.Delete(@"C:\rcs\versisendemail\reports\eod.txt");
        }


    }

    class INIFile
    {
        private string filePath;

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section,
        string key,
        string val,
        string filePath);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section,
        string key,
        string def,
        StringBuilder retVal,
        int size,
        string filePath);

        public INIFile(string filePath)
        {
            this.filePath = filePath;
        }

        public void Write(string section, string key, string value)
        {
            WritePrivateProfileString(section, key, value.ToLower(), this.filePath);
        }

        public string Read(string section, string key)
        {
            StringBuilder SB = new StringBuilder(255);
            int i = GetPrivateProfileString(section, key, "", SB, 255, this.filePath);
            return SB.ToString();
        }

        public string FilePath
        {
            get { return this.filePath; }
            set { this.filePath = value; }
        }
    }

    }

}

CodePudding user response:

Your attachement are not disposed (https://docs.microsoft.com/fr-fr/dotnet/api/system.net.mail.attachment?view=net-6.0).

            System.Net.Mail.Attachment attachment;
            attachment = new System.Net.Mail.Attachment(@"c:\rcs\versisendemail\reports\eod.txt");
            mailMessage.Attachments.Add(attachment);

Try read the file with a MemoryStream in order to avoid file lock like :

            System.Net.Mail.Attachment attachment;
            attachment = new System.Net.Mail.Attachment(new MemoryStream(File.ReadAllBytes( @"c:\rcs\versisendemail\reports\eod.txt")), "text");

CodePudding user response:

As a general rule, if you use something that implements IDisposable (like streams, for example), you need to dispose them eventually.

Here, MailMessage is disposable. Disposing it also recursively disposes everything it holds, like attachments, views, etc. So all you need to do is declare your mail message with a using statement:

using MailMessage mailMessage = new MailMessage();

That way, when the message goes out of scope, it'll get disposed, and will then dispose its attachments, and thus the file will be unlocked.

  •  Tags:  
  • c#
  • Related