File.Move no longer working

kriscs1

Member
Joined
Jan 30, 2020
Messages
6
Programming Experience
Beginner
Hi,
I have a program that checks a folder for Excel files, imports their contents via SQL to a database table, then moves the Excel file to a 'Completed' folder.
This worked flawlessly last year. Unfortunatley, I am now getting the following error:

System.IO.IOException: The process cannot access the file because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.__Error.WinIOError()
at System.IO.File.InternalMove(String sourceFileName, String destFileName, Boolean checkHost)
at System.IO.File.Move(String sourceFileName, String destFileName)
at UploadAttendanceLogtoSQLTaible.Program.InsertExcelRecords(String filePath, String destinationPath) in C:\Users\**Redacted**\Google Drive\Teaching\Software\UploadAttendanceLog\UploadAttendanceLogtoSQLTable\Program.cs:line 159
The data uploads just fine. It is just moving the file afterwards that is the problem.

Here is the relevant code:
C#:
        private static void InsertExcelRecords(string filePath, string destinationPath)
        {
            LogWriter Log = new LogWriter("");
            try
            {
                //  ExcelConn(_path); 
                string constr = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES;""", filePath);
                OleDbConnection Econ = new OleDbConnection(constr);
                string Query = string.Format("Select [Student ID],[Activity],[Session Name],[Date],[Time],[Status],[Sub-Session Name] FROM [{0}]", arg0: "data_RawAttendanceLog$");
                OleDbCommand Ecom = new OleDbCommand(Query, Econ);
                Econ.Open();

                //Create one dataset and fill this data set with this selected items, using oledbdataadpter
                DataSet ds = new DataSet();
                OleDbDataAdapter oda = new OleDbDataAdapter(Query, Econ);
                Econ.Close();
                oda.Fill(ds);
                DataTable Exceldt = ds.Tables[0];

                for (int i = Exceldt.Rows.Count - 1; i >= 0; i--)
                {
                    if (Exceldt.Rows[i]["Student ID"] == DBNull.Value)
                    {
                        Exceldt.Rows[i].Delete();
                    }
                }
                Exceldt.AcceptChanges();

                //creating object of SqlBulkCopy     
                string csDestination = "server = " + GetValueFromFile("server") + "; database = " + GetValueFromFile("database") + "; Trusted_Connection=True"; // User ID = *redacted*; Password = ; Trusted_Connection=True";

                using (SqlConnection con = new SqlConnection(csDestination))
                {

                    SqlBulkCopy objbulk = new SqlBulkCopy(con);
                    //assigning Destination table name     
                    objbulk.DestinationTableName =  GetValueFromFile("DestinationTableName");
                    //Mapping Table column   

                    objbulk.ColumnMappings.Add("[Student ID]", "StudentID");
                    objbulk.ColumnMappings.Add("[Activity]", "Activity");
                    objbulk.ColumnMappings.Add("[Session Name]", "SessionName");
                    objbulk.ColumnMappings.Add("[Date]", "SessionDate");
                    objbulk.ColumnMappings.Add("[Time]", "SessionTime");
                    objbulk.ColumnMappings.Add("[Status]", "SessionStatus");
                    objbulk.ColumnMappings.Add("[Sub-Session Name]", "SubSessionName");

                    //inserting Datatable Records to DataBase   
                    SqlConnection sqlConnection = new SqlConnection();

                    con.Open();
                    objbulk.WriteToServer(Exceldt);

                    Console.WriteLine("Upload successful.");
                    Log.LogWrite("Upload successful.");
                    Econ.Close();
                    Log.LogWrite("Moving " + filePath + " to " + destinationPath);
                    File.Move(filePath, destinationPath);

                }

            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("network-related"))
                {
                    Console.WriteLine("Cancelled. No Network access.");
                    return;
                }
                else
                {
                    Console.WriteLine(string.Format("Upload has not been imported due to: {0}", ex.Message));
                    Log.LogWrite(string.Format("Upload has not been imported due to: {0}", ex.Message));
                    Console.WriteLine("Press any key to close...");
                    ShowWindow(GetConsoleWindow(), SW_SHOW);
                    Console.ReadKey();
                }

            }

        }

    }
Let me know if you need any more information.
Thanks so much.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,049
Location
Sydney, Australia
Programming Experience
10+
The Excel file is clearly still open somewhere when you call Move. At a glance, I can't see specifically where that would be in your code, although your code is somewhat more convoluted than it needs to be. ADO.NET does use connection pooling but I'm not sure whether that is the case for Excel files. In the case of "proper" databases, the actual database connection is at a lower level and remains open for some time after you close your ADO.NET connection, to speed up access in case it needs to be used again. I'm not sure whether that happens with Excel files but I would have thought not. You can turn off connection pooling in a connection string in some cases but it wouldn't be supported if pooling itself is not supported.

As I was writing this, it occurred to me that I was assuming the issue was with the source file but perhaps it is the destination file that is the problem. You don't have another file with the same name in the destination folder already open, do you?
 

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,378
Location
UK
Programming Experience
10+
There is nothing wrong with how your code moves the file. Problem is painfully obvious and tells you in the error. What do you think this means :
The process cannot access the file because it is being used by another process. ?

For any code that opens the file for any reason, must be forced to release the file when its finished reading or opening it. Best way to do this is to use using blocks since they are self disposing of the resources they use.

What is the filePath being passed in? And why do you have that path at the end of your constr?
 

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,378
Location
UK
Programming Experience
10+
I didn't see the string format. Long day on the road John.

I didn't see the path was being fed to the datasource. Half asleep here
 

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,378
Location
UK
Programming Experience
10+
you probably ought to be fully asleep.
I should be. The joys of being self employed and working for a international tech company.

Shouldn't you get a different error if the destination file already exists? I'll check it out before bed, and post back.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,049
Location
Sydney, Australia
Programming Experience
10+
Shouldn't you get a different error if the destination file already exists? I'll check it out before bed, and post back.
Not sure. If an existing file should be overwritten then possibly not.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,575
Location
Virginia Beach, VA
Programming Experience
10+
Another thing to look at is your choice of Antivirus. Some AV software keeps files open while it performs it's scans. To make matters worse, some of them do DLL injection into applications (including your own app), so they are running as that process.

Use ProcMon from SysInternals to see who has file handles open on the file if disabling AV (temporarily) still results in the same error.
 

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,378
Location
UK
Programming Experience
10+
Right.

So if the file already exists in the destination, and you try moving the file you will get : System.IO.IOException: 'Cannot create a file when that file already exists.
If the file is open in your application by way of not disposing of any used resources where you've opened or read the file, you will get: System.IO.IOException: The process cannot access the file because it is being used by another process.

See this ref for using blocks or the one in my signature : OleDbCommand Class (System.Data.OleDb) It should eradicate the problem. Wrap as much of your code in using blocks unless you want to handle all your disposing manually.

@Skydiver wouldn't what you said re the AV be the same as opening a file manually? I can open files manually (external not with code) and still be able to move them without exception.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,049
Location
Sydney, Australia
Programming Experience
10+
I can open files manually (external not with code) and still be able to move them without exception.
It depends on the app and how it handles the file. Some apps open a file, read its contents and then close the file. I believe that Notepad works that way. Office apps, on the other hand, open a file and keep it open until you explicitly close it. I have found that i can't read Office files using ADO.NET if an Office app has them open.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,575
Location
Virginia Beach, VA
Programming Experience
10+
Jim beat me to it.
 

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,378
Location
UK
Programming Experience
10+
I assume they read the contents into memory, so they can dispose of the actual resources used by opening the file. Smart, and upon closing applications such as Notepad++, I assume they do it as you mentioned. Upon closing the application, the files contents are retained in the application regardless if you save or not. I guess open non saved files are wrote to a internal database when the program exits. Interesting some apps will give me an error. (y)

Bed time for me, see you guys tomorrow.

Edit : Some of which I was playing with to replicate the error. Notice how if the file is openread, it will throw a woobler with the exception :
C#:
        private void Form1_Load(object sender, EventArgs e)
        {
            File.OpenRead(Path.Combine(Application.StartupPath, "ddoc.txt"));
            DoFile(Path.Combine(Application.StartupPath, "ddoc.txt"), Path.Combine(Application.StartupPath, "ddoc2.txt"));
        }

        private void DoFile(string In, string Out)
        {
            File.Move(In, Out);
        }
 
Last edited:

kriscs1

Member
Joined
Jan 30, 2020
Messages
6
Programming Experience
Beginner
Thank you for responding.

The strange thing is this same program worked for over a year just fine. I think it stopped working since I uninstalled and reinstalled Microsoft Office, so maybe there was a change there.
The file definitely doesn't already exist and the only thing opening it is my program. I have tried changing the directories to no avail.

I am unable to disable the AV as it is locked by my company, however it is the same AV that was installed last year.

Are saying if I somehow try to wrap more of the function in a using block that should fix the issue? I tried it like this (SQL struff removed) but it still has the same issue:

C#:
 using (OleDbConnection Econ = new OleDbConnection(constr))
                {
                string Query = string.Format("Select [Student ID],[Activity],[Session Name],[Date],[Time],[Status],[Sub-Session Name] FROM [{0}]", arg0: "data_RawAttendanceLog$");
                    OleDbCommand Ecom = new OleDbCommand(Query, Econ);
               
                    Econ.Open();

                    //Create one dataset and fill this data set with this selected items, using oledbdataadpter
                    DataSet ds = new DataSet();
                    OleDbDataAdapter oda = new OleDbDataAdapter(Query, Econ);
                    Econ.Close();
                    oda.Fill(ds);
                    DataTable Exceldt = ds.Tables[0];

                    for (int i = Exceldt.Rows.Count - 1; i >= 0; i--)
                    {
                        if (Exceldt.Rows[i]["Student ID"] == DBNull.Value)
                        {
                            Exceldt.Rows[i].Delete();
                        }
                    }
                    Exceldt.AcceptChanges();
                }
             
                    File.Move(filePath, destinationPath);
I assume they read the contents into memory, so they can dispose of the actual resources used by opening the file. Smart, and upon closing applications such as Notepad++, I assume they do it as you mentioned. Upon closing the application, the files contents are retained in the application regardless if you save or not. I guess open non saved files are wrote to a internal database when the program exits. Interesting some apps will give me an error. (y)

Bed time for me, see you guys tomorrow.

Edit : Some of which I was playing with to replicate the error. Notice how if the file is openread, it will throw a woobler with the exception :
C#:
        private void Form1_Load(object sender, EventArgs e)
        {
            File.OpenRead(Path.Combine(Application.StartupPath, "ddoc.txt"));
            DoFile(Path.Combine(Application.StartupPath, "ddoc.txt"), Path.Combine(Application.StartupPath, "ddoc2.txt"));
        }

        private void DoFile(string In, string Out)
        {
            File.Move(In, Out);
        }
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,575
Location
Virginia Beach, VA
Programming Experience
10+
Sorry, Process Explorer, not ProcMon. (My team uses ProcMon extensively to troubleshoot or monitoring what applications are trying to open or read). If you are just interested in open file handles, use Process Explorer or Handle. All three are available on SysInternals.com.
 

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,378
Location
UK
Programming Experience
10+
You should compartmentalise your code and break it down into functions with return types and use additional methods. For example, where ever you are executing that code above, you should be allowing the method to execute the statements, and then return to the calling code, where you would and should execute your next method, which should be to remove the excel file you no longer need.

Also, look at all these using statements you can use. Since I don't see where you are disposing of any of your object usage, you stand more chance of narrowing the problem by breaking your code up into sections that perform one task per method/function. :

C#:
                using (OleDbConnection Econ = new OleDbConnection(""))
                {           
                }
                using (OleDbCommand Ecom = new OleDbCommand(Query, Econ))
                {
                }
                using (DataSet ds = new DataSet())
                {
                }
                using (OleDbDataAdapter oda = new OleDbDataAdapter(Query, Econ))
                {
                }
                using (DataTable Exceldt = ds.Tables[0])
                {
                }
Lastly, you should not be trying to remove the file from the same method as that which its principle function was to be used for DB queries, and not deleting files. The error you are getting is because your application is opening that file and therefore can't remove it while its open somewhere else in your code. This is where writing modular self-disposing/reusable code really does help. Start looking at other places where files are being opened, and make sure when a method/function is done using a file, make sure that it is releasing the resources it's used.
 

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,378
Location
UK
Programming Experience
10+
Just one other thing, which might help you with future development. If you stick to the OOR (Object Orientation Rules) - Just read the articles in the links. Passing around your data, you will find it much more efficient and much easier to avoid issues as this. Go back and review previous code where you are opening this same file.
 

kriscs1

Member
Joined
Jan 30, 2020
Messages
6
Programming Experience
Beginner
Thanks again. You can probably tell this is my first c# program (which is mostly copied and pasted together from various websites and forums!). I'm more used to using basic.
I have made a few of those changes and will continue to plug away at it until I get get it to work.
I haven't managed to identify another process using the file yet but will also keep trying. EDIT: According to Process Explorer, only this program is using the file.

This is the entire program so far with the SQL table upload code removed along with a sample excel file:


C#:
using System;
using System.IO;
using System.Data.OleDb;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;

namespace UploadAttendanceLogtoSQLTable
{

    class Program
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        const int SW_HIDE = 0;
        const int SW_SHOW = 5;

        static void Main(string[] args)
        {
            ShowWindow(GetConsoleWindow(), SW_HIDE);

            LogWriter Log = new LogWriter("");
            Log.LogWrite("-----------------------------------------------------------");
            Log.LogWrite(DateTime.Now.ToLongTimeString() + " " + DateTime.Now.ToLongDateString());
            Log.LogWrite("Beginning scan and upload of Attendance Logs...");
            Console.WriteLine("Beginning scan and upload of Attendance Logs...");

            string sourceFolder = "C:\\Users\\Name\\Desktop\\Test"; // GetValueFromFile("sourceFolder");
            string destinationFolder = "C:\\Users\\Name\\Desktop\\Test\\Completed"; //  GetValueFromFile("destinationFolder");

            foreach (string filePath in Directory.GetFiles(sourceFolder))
            {
                try
                {
                    string fileExt = System.IO.Path.GetExtension(filePath);
                    string fileName = Path.GetFileName(filePath);
                    string destinationPath = destinationFolder + "\\" + fileName;

                    if (fileExt == ".xlsx")
                    {

                        Console.WriteLine("");
                        Console.WriteLine("Uploading... " + fileName);
                        Log.LogWrite("");
                        Log.LogWrite("Uploading... " + fileName);

                        if (InsertExcelRecords(filePath, destinationPath))
                        {
                            Console.WriteLine("Moving... " + fileName);
                            Log.LogWrite("Moving... " + fileName);
                            try
                            {
                                File.Move(filePath, destinationPath);
                            }
                            catch (Exception ex)
                            {
                                ErrorOccured(ex.Message);
                            }
                        }
                    }
                    else
                    {
                        File.Delete(filePath);
                    }
                }
                catch (Exception ex)
                {
                    ErrorOccured(ex.Message);
                }

            }

            Console.WriteLine("Program Complete");
            Log.LogWrite("Program Complete");
        }


        public static string GetValueFromFile(string valueName)
        {
            string fileValue;
            string[] lines = System.IO.File.ReadAllLines("UploadAttendanceLogtoSQLTableConfig.txt");
            foreach (string line in lines)
            {
                string[] words = line.Split('=');
                if (words[0] == valueName)
                {
                    fileValue = words[1];
                    return fileValue;
                }
            }
            return "N/A";
        }


        public static bool InsertExcelRecords(string filePath, string destinationPath)
        {
            LogWriter Log = new LogWriter("");
            try
            {
                //  ExcelConn(_path);
                string constr = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES;""", filePath);
                using (OleDbConnection Econ = new OleDbConnection(constr))
                {
                    string Query = string.Format("Select [Student ID],[Activity],[Session Name],[Date],[Time],[Status],[Sub-Session Name] FROM [{0}]", arg0: "data_RawAttendanceLog$");
                    using (OleDbCommand Ecom = new OleDbCommand(Query, Econ))
                    {

                        Econ.Open();

                        //Create one dataset and fill this data set with this selected items, using oledbdataadpter
                        using (DataSet ds = new DataSet())
                        {
                            using (OleDbDataAdapter oda = new OleDbDataAdapter(Query, Econ))
                            {

                                oda.Fill(ds);
                                using (DataTable Exceldt = ds.Tables[0])
                                {

                                    for (int i = Exceldt.Rows.Count - 1; i >= 0; i--)
                                    {
                                        if (Exceldt.Rows[i]["Student ID"] == DBNull.Value)
                                        {
                                            Exceldt.Rows[i].Delete();
                                        }
                                    }
                                    Exceldt.AcceptChanges();
                                }
                            }
                        }
                    }
                    Econ.Close();
                }
                return true;

            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("network-related"))
                {
                    Console.WriteLine("Cancelled. No Network access.");
                    return false;
                }
                else
                {
                    ErrorOccured(ex.Message);
                    return false;
                }

            }

        }

        private static void ErrorOccured(string errMessage)
        {
            LogWriter Log = new LogWriter("");
            Console.WriteLine(string.Format("The following error occured: {0}", errMessage));
            Log.LogWrite(string.Format("The following error occured: {0}", errMessage));
            Console.WriteLine("Press any key to continue...");
            ShowWindow(GetConsoleWindow(), SW_SHOW);
            Console.ReadKey();
        }

    }



    public class LogWriter
    {
        private string m_exePath = string.Empty;
        public LogWriter(string logMessage)
        {
            LogWrite(logMessage);
        }
        public void LogWrite(string logMessage)
        {
            m_exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            try
            {
                using (StreamWriter w = File.AppendText(m_exePath + "\\" + "log.txt"))
                {
                    Log(logMessage, w);
                }
            }
            catch (Exception ex)
            {
            }
        }

        public void Log(string logMessage, TextWriter txtWriter)
        {
            try
            {
                txtWriter.WriteLine(DateTime.Now.ToLongTimeString() + " " + logMessage);
            }
            catch (Exception ex)
            {

            }
        }
    }



}
 
Last edited:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,575
Location
Virginia Beach, VA
Programming Experience
10+
I ran your code (changed the paths to be appropriate for my machine) without any issues. The call to File.Move() didn't throw any exceptions. I have 64-bit Office 2019 and Avira.

As a warning to others who may decide to try to copy and paste this code to run. Beware lines 67-70 which will delete files from the sourceFolder.
 

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,378
Location
UK
Programming Experience
10+
I changed some of the code slightly, and removed a lot of redundant code. But you still have a lot of house keeping to do, and editing. There is so much of the code which needs breaking down and segregate your code into functions and only have one function perform one task, and the same with each method. Currently the code below works, but if you do not delete the file from the destination folder, it will throw an error which you are catching fairly silently, and not actually dealing with why it was raised. Do not catch errors and not handle the issue being presented. That's like the crappiest way to write bad code and as a result you will not know where your problem is should one arise when you publish your application. I can see that you are writing out the issue, but you really ought to handle the issue and not just verbosely log it. So don't do that, unless you are going to handle the issue at first hand.

Change this :
C#:
            foreach (string filePath in Directory.GetFiles(sourceFolder))
            {
                try
                {
                    string fileExt = System.IO.Path.GetExtension(filePath);
                    string fileName = Path.GetFileName(filePath);
                    string destinationPath = destinationFolder + "\\" + fileName;

                    if (fileExt == ".xlsx")
                    {

                        Console.WriteLine("");
                        Console.WriteLine("Uploading... " + fileName);
                        Log.LogWrite("");
                        Log.LogWrite("Uploading... " + fileName);

                        if (InsertExcelRecords(filePath, destinationPath))
                        {
                            Console.WriteLine("Moving... " + fileName);
                            Log.LogWrite("Moving... " + fileName);
                            try
                            {
                                File.Move(filePath, destinationPath);
                            }
                            catch (Exception ex)
                            {
                                ErrorOccured(ex.Message);
                            }
                        }
                    }
                    else
                    {
                        File.Delete(filePath);
                    }
                }
                catch (Exception ex)
                {
                    ErrorOccured(ex.Message);
                }
            }
To This :
C#:
            Create_Folder_Structure(sourceFolder, destinationFolder); bool error = false;
            foreach (string filePath in Directory.GetFiles(sourceFolder))
            {
                try
                {
                    if (Path.GetExtension(filePath) == ".xlsx")
                    {
                        Console.WriteLine(""); string msg = string.Concat("Uploading... ", Path.GetFileName(filePath));
                        Console.WriteLine(msg);
                        Log.LogWrite("");
                        Log.LogWrite(msg);
                        if (InsertExcelRecords(filePath, Path.Combine(destinationFolder, Path.GetFileName(filePath))))
                        {
                            msg = "Moving... " + Path.GetFileName(filePath);
                            Console.WriteLine(msg);
                            Log.LogWrite(msg);
                            File.Move(filePath, Path.Combine(destinationFolder, Path.GetFileName(filePath)));
                        }
                    }
                    else
                    {
                        File.Delete(filePath);
                    }
                }
                catch (IOException nsex)
                {
                    error = true;
                }
                catch (Exception ex)
                {
                    ErrorOccured(ex.Message);
                }
                finally
                {
                    if (error && FileDelete(Path.Combine(destinationFolder, Path.GetFileName(filePath))))
                    {
                        FileMove(filePath, Path.Combine(destinationFolder, Path.GetFileName(filePath)));
                    }
                }
            }
Then add these :
C#:
        private static bool FileMove(string origin, string destination)
        {
            try
            {
                File.Move(origin, destination);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        private static bool FileDelete(string destination)
        {
            try
            {
                File.Delete(destination);
                return true;
            }
            catch (Exception ex)
            {
                return false;
                //Handle error
            }
        }

        private static void Create_Folder_Structure(string sourceFolder, string destinationFolder)
        {
            if (!Directory.Exists(sourceFolder))
                Directory.CreateDirectory(sourceFolder);
            if (!Directory.Exists(destinationFolder))
                Directory.CreateDirectory(destinationFolder);
        }
Completed you will end up with this :
C#:
using System;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;

namespace UploadAttendanceLogtoSQLTable
{
    internal static class Program
    {
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetConsoleWindow();

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private const int SW_HIDE = 0;
        private const int SW_SHOW = 5;

        private static void Main(string[] args)
        {
            ShowWindow(GetConsoleWindow(), SW_HIDE);

            LogWriter Log = new LogWriter("");
            Log.LogWrite("-----------------------------------------------------------");
            Log.LogWrite(DateTime.Now.ToLongTimeString() + " " + DateTime.Now.ToLongDateString());
            Log.LogWrite("Beginning scan and upload of Attendance Logs...");
            Console.WriteLine("Beginning scan and upload of Attendance Logs...");

            string sourceFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test"); // GetValueFromFile("sourceFolder");
            string destinationFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), @"Test\Completed"); //  GetValueFromFile("destinationFolder");
            Create_Folder_Structure(sourceFolder, destinationFolder); bool error = false;
            foreach (string filePath in Directory.GetFiles(sourceFolder))
            {
                try
                {
                    if (Path.GetExtension(filePath) == ".xlsx")
                    {
                        Console.WriteLine(""); string msg = string.Concat("Uploading... ", Path.GetFileName(filePath));
                        Console.WriteLine(msg);
                        Log.LogWrite("");
                        Log.LogWrite(msg);
                        if (InsertExcelRecords(filePath, Path.Combine(destinationFolder, Path.GetFileName(filePath))))
                        {
                            msg = "Moving... " + Path.GetFileName(filePath);
                            Console.WriteLine(msg);
                            Log.LogWrite(msg);
                            File.Move(filePath, Path.Combine(destinationFolder, Path.GetFileName(filePath)));
                        }
                    }
                    else
                    {
                        File.Delete(filePath);
                    }
                }
                catch (IOException nsex)
                {
                    error = true;
                }
                catch (Exception ex)
                {
                    ErrorOccured(ex.Message);
                }
                finally
                {
                    if (error && FileDelete(Path.Combine(destinationFolder, Path.GetFileName(filePath))))
                    {
                        FileMove(filePath, Path.Combine(destinationFolder, Path.GetFileName(filePath)));
                    }
                }
            }

            Console.WriteLine("Program Complete");
            Log.LogWrite("Program Complete");
        }

        private static bool FileMove(string origin, string destination)
        {
            try
            {
                File.Move(origin, destination);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        private static bool FileDelete(string destination)
        {
            try
            {
                File.Delete(destination);
                return true;
            }
            catch (Exception ex)
            {
                return false;
                //Handle error
            }
        }

        private static void Create_Folder_Structure(string sourceFolder, string destinationFolder)
        {
            if (!Directory.Exists(sourceFolder))
                Directory.CreateDirectory(sourceFolder);
            if (!Directory.Exists(destinationFolder))
                Directory.CreateDirectory(destinationFolder);
        }

        public static string GetValueFromFile(string valueName)
        {
            foreach (var words in from string line in File.ReadAllLines("UploadAttendanceLogtoSQLTableConfig.txt")
                                  let words = line.Split('=')
                                  where words[0] == valueName
                                  select words)
            {
                return words[1];
            }
            return "N/A";
        }

        public static bool InsertExcelRecords(string filePath, string destinationPath)
        {
            LogWriter Log = new LogWriter("");
            try
            {
                using (OleDbConnection Econ = new OleDbConnection(string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES;""", filePath)))
                {
                    string Query = string.Format("Select [Student ID],[Activity],[Session Name],[Date],[Time],[Status],[Sub-Session Name] FROM [{0}]", arg0: "data_RawAttendanceLog$");
                    using (OleDbCommand Ecom = new OleDbCommand(Query, Econ))
                    {
                        Econ.Open();

                        //Create one dataset and fill this data set with this selected items, using oledbdataadpter
                        using (DataSet ds = new DataSet())
                        {
                            using (OleDbDataAdapter oda = new OleDbDataAdapter(Query, Econ))
                            {
                                oda.Fill(ds);
                                using (DataTable Exceldt = ds.Tables[0])
                                {
                                    for (int i = Exceldt.Rows.Count - 1; i >= 0; i--)
                                    {
                                        if (Exceldt.Rows[i]["Student ID"] == DBNull.Value)
                                        {
                                            Exceldt.Rows[i].Delete();
                                        }
                                    }
                                    Exceldt.AcceptChanges();
                                }
                            }
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("network-related"))
                {
                    Console.WriteLine("Canceled. No Network access.");
                    return false;
                }
                else
                {
                    ErrorOccured(ex.Message);
                    return false;
                }
            }
        }

        private static void ErrorOccured(string errMessage)
        {
            LogWriter Log = new LogWriter("");
            Console.WriteLine(string.Format("The following error occured: {0}", errMessage));
            Log.LogWrite(string.Format("The following error occured: {0}", errMessage));
            Console.WriteLine("Press any key to continue...");
            ShowWindow(GetConsoleWindow(), SW_SHOW);
            Console.ReadKey();
        }
    }

    public class LogWriter
    {
        private string m_exePath = string.Empty;

        public LogWriter(string logMessage) => LogWrite(logMessage);

        public void LogWrite(string logMessage)
        {
            m_exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            try
            {
                using (TextWriter txt_Writer = File.AppendText(Path.Combine(m_exePath, "log.txt")))
                    txt_Writer.WriteLine(string.Concat(DateTime.Now.ToLongTimeString(), string.Empty.PadRight(1), logMessage));
            }
            catch (Exception ex)
            {
            }
        }

        public void Log(string logMessage, TextWriter txtWriter)
        {
            try
            {
                using (txtWriter)
                    txtWriter.WriteLine(string.Concat(DateTime.Now.ToLongTimeString(), string.Empty.PadRight(1), logMessage));
            }
            catch (Exception ex)
            {
            }
        }
    }
}
Just as an aside note, while this does fix your error, you still need to tidy your code, and fix up some typos in your grammar as well as what i said on post 17. Your problem was, that you were not checking if a file already existed in the destination folder, and if the file was ever moved to the completed directory, and upon trying to move the same filename to that directory, you were receiving the IO error as a result. The code I changed resolves this and some other minor issues.
 
Top Bottom