File.Move不再起作用

kriscs1

会员
已加入
2020年1月30日
留言内容
6
编程经验
Beginner
你好
我有一个程序检查文件夹中是否有Excel文件,然后通过SQL将其内容导入数据库表,然后将Excel文件移至“已完成”文件夹。
去年,此操作完美无缺。 Unfortunatley,我现在收到以下错误:

System.IO.IOException:该进程无法访问该文件,因为它正在被另一个进程使用。
在System.IO .__ Error.WinIOError(Int32 errorCode,字符串mayFullPath)
在System.IO .__ Error.WinIOError()
在System.IO.File.InternalMove(String sourceFileName,String destFileName,Boolean checkHost)
在System.IO.File.Move(字符串sourceFileName,字符串destFileName)
159:

数据上传就可以了。这只是问题之后才移动文件。

以下是相关代码:
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 和 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();
                }

            }

        }

    }

让我知道您是否需要更多信息。
非常感谢。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,502
地点
悉尼,澳大利亚
编程经验
10+
当您致电时,Excel文件显然仍在某个位置打开 移动。乍一看,虽然您的代码比所需的要复杂得多,但是我看不到代码在代码中的具体位置。 ADO.NET确实使用连接池,但是我不确定Excel文件是否是如此。如果是"proper"数据库,实际的数据库连接处于较低级别,并且在关闭ADO.NET连接后会保持打开状态一段时间,以加快访问速度,以防万一需要再次使用它。我不确定Excel文件是否会发生这种情况,但我认为不会。在某些情况下,您可以在连接字符串中关闭连接池,但是如果不支持池本身,则不支持该连接池。

在我撰写本文时,我想到我以为问题出在源文件上,但问题可能出在目标文件上。您没有在目标文件夹中打开另一个具有相同名称的文件,对吗?
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
您的代码如何移动文件没有错。问题很明显,并告诉您错误。你认为这是什么意思 :
The process cannot access the file because it is being used by another process. ?

对于出于任何原因打开文件的任何代码,必须在完成读取或打开文件后强制释放文件。最好的方法是使用using块,因为它们会自行处置使用的资源。

传入的文件路径是什么?为何在构建结束时要走那条路?
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
我没有看到字符串格式。约翰在路上漫长的一天。

我没有看到路径被馈送到数据源。在这里睡着了
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
您可能应该完全入睡。
我应该。成为个体经营者并在一家国际科技公司工作的乐趣。

如果目标文件已经存在,您是否应该得到另一个错误?我睡前检查一下,然后寄回去。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,502
地点
悉尼,澳大利亚
编程经验
10+
如果目标文件已经存在,您是否应该得到另一个错误?我睡前检查一下,然后寄回去。
不确定。如果应该覆盖现有文件,则可能不会。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
要注意的另一件事是您选择的防病毒软件。某些AV软件在执行扫描时会保持文件打开状态。更糟糕的是,其中一些将DLL注入到应用程序(包括您自己的应用程序)中,因此它们作为该进程运行。

如果暂时禁用AV仍然导致相同的错误,请使用SysInternals的ProcMon查看谁在文件上打开了文件句柄。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
对。

因此,如果该文件已在目标位置中,然后尝试移动该文件,则会得到: System.IO.IOException: 'Cannot create a file when that file already exists.
如果在应用程序中打开文件是通过不丢弃已打开或读取文件的任何已使用资源的方式,您将获得: System.IO.IOException:该进程无法访问该文件,因为它正在被另一个进程使用。

有关使用块或我的签名中的块,请参阅此参考: OleDbCommand类(System.Data.OleDb) 它可以消除问题。除非要手动处理所有处置,否则在使用块中包装尽可能多的代码。

@跳伞 您说的AV与手动打开文件不一样吗?我可以手动打开文件(外部不带代码),并且仍然可以无例外地移动它们。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,502
地点
悉尼,澳大利亚
编程经验
10+
我可以手动打开文件(外部不带代码),并且仍然可以无例外地移动它们。
这取决于应用程序及其处理文件的方式。一些应用程序会打开文件,读取其内容,然后关闭文件。我相信记事本可以这样工作。另一方面,Office应用程序会打开一个文件并保持打开状态,直到您明确关闭它为止。我发现如果Office应用程序将其打开,则无法使用ADO.NET读取Office文件。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
我假设他们将内容读入内存,因此他们可以通过打开文件来处置实际使用的资源。很聪明,在关闭诸如Notepad ++之类的应用程序时,我认为它们已经按照您所说的进行了。关闭应用程序后,无论是否保存,文件内容都将保留在应用程序中。我猜打开的未保存文件会在程序退出时写入内部数据库。有趣的一些应用程序会给我一个错误。 (y)

我的上床时间,明天见。

编辑:我正在与其中一些复制错误。请注意,如果文件是openread,它将抛出一个woobler,但例外情况是:
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

会员
已加入
2020年1月30日
留言内容
6
编程经验
Beginner
感谢您的回应。

奇怪的是,这个程序工作了一年多就好了。我认为自从我卸载并重新安装Microsoft Office以来,它就停止了工作,因此也许在那里有所更改。
该文件绝对不存在,唯一打开它的是我的程序。我尝试将目录更改为无济于事。

我无法禁用该AV,因为它已被我的公司锁定,但是与去年安装的AV相同。

是说我是否以某种方式尝试将更多功能包装在应该解决该问题的using块中?我这样尝试过(已删除SQL struff),但仍然存在相同的问题:

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 和 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);

我假设他们将内容读入内存,因此他们可以通过打开文件来处置实际使用的资源。很聪明,在关闭诸如Notepad ++之类的应用程序时,我认为它们已经按照您所说的进行了。关闭应用程序后,无论是否保存,文件内容都将保留在应用程序中。我猜打开的未保存文件会在程序退出时写入内部数据库。有趣的一些应用程序会给我一个错误。 (y)

我的上床时间,明天见。

编辑:我正在与其中一些复制错误。请注意,如果文件是openread,它将抛出一个woobler,但例外情况是:
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);
        }
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
对不起,Process Explorer,不是 ProcMon。 (我的团队广泛使用ProcMon来排除故障或监视正在尝试打开或读取的应用程序)。如果您只对打开文件句柄感兴趣,请使用 流程浏览器 要么 处理。这三个都可以在SysInternals.com上获得。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
您应该分隔代码,并将其分解为具有返回类型的函数,并使用其他方法。例如,在上面执行该代码的任何地方,都应允许该方法执行该语句,然后返回到调用代码,在此地方并且应执行下一个方法,该方法应该是删除您的excel文件。不再需要。

另外,请查看所有可以使用的using语句。由于我看不到要处理任何对象的使用情况,因此您更有机会通过将代码分解为每个方法/功能执行一项任务的部分来缩小问题的范围。 :

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])
                {
                }
最后,您不应该尝试从与其主要功能用于数据库查询的方法相同的方法中删除文件,而不是删除文件。您收到的错误是因为您的应用程序正在打开该文件,因此在代码中其他位置打开该文件时无法将其删除。这是编写模块化的自我处置/可重用代码确实有帮助的地方。开始查看打开文件的其他位置,并确定何时使用文件完成方法/功能,并确保它释放了所使用的资源。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
只是另一件事,可能对您的未来发展有所帮助。如果你坚持 OOR (对象定向规则)-只需阅读链接中的文章。遍历数据,您会发现它效率更高,并且更容易避免此类问题。返回并查看以前的代码,您将在其中打开同一文件。
 

kriscs1

会员
已加入
2020年1月30日
留言内容
6
编程经验
Beginner
再次感谢。您可能会说这是我的第一个C#程序(通常是从各个网站和论坛复制并粘贴到一起的!)。我更习惯使用基本的。
我做了一些更改,并将继续使用它,直到我开始使用它。
我尚未设法使用该文件标识另一个进程,但也将继续尝试。编辑:根据Process Explorer,仅此程序正在使用该文件。

到目前为止,这是整个程序,其中删除了SQL表上传代码以及一个示例excel文件:


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 和 upload of Attendance Logs...");
            Console.WriteLine("Beginning scan 和 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 和 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:

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
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 和 Avira.

作为对可能决定尝试复制并粘贴此代码以使其运行的其他人的警告。 当心第67-70行,这将删除 sourceFolder.
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
我稍微更改了一些代码,并删除了很多冗余代码。但是您还有很多工作要做和编辑。有太多的代码需要分解,并将您的代码分成多个函数,只有一个函数执行一项任务,每种方法都相同。当前,下面的代码有效,但是,如果不从目标文件夹中删除文件,它将抛出一个错误,而您正在默默地捕获该错误,而实际上并没有处理引起该错误的原因。不要发现错误,也不能处理出现的问题。这就像编写最糟糕的代码的最糟糕的方式,结果您将不知道发布应用程序时出现问题的地方。我可以看到您正在写问题,但您确实应该处理该问题,而不仅仅是冗长地记录下来。因此,请勿这样做,除非您要直接处理此问题。

改变这个:
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);
                }
            }

为此:
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)));
                    }
                }
            }
然后添加这些:
C#:
        private static bool FileMove(string 要么igin, 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);
        }
完成后,您将得到以下结果:
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 和 upload of Attendance Logs...");
            Console.WriteLine("Beginning scan 和 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 要么igin, 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 和 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)
            {
            }
        }
    }
}
顺便提一下,虽然这确实可以解决您的错误,但是您仍然需要整理代码,并修正语法中的错字以及我在第17条中所说的内容。您的问题是,您没有检查是否该文件已经存在于目标文件夹中,并且如果该文件曾经被移至完整目录,并且在尝试将相同文件名移至该目录时,您将收到IO错误。我更改的代码解决了此问题以及其他一些小问题。
 
最佳 底部