C# 如果文件损坏,OleDbConnection将锁定Excel xls文件

C# 如果文件损坏,OleDbConnection将锁定Excel xls文件,c#,.net,excel,oledbconnection,filehandle,C#,.net,Excel,Oledbconnection,Filehandle,我有一个将Excel(*.xls)导入数据库的遗留代码,然后在处理后将文件移动到特定目录 该代码工作正常,但有一种情况除外,即文件已损坏(即使MS Excel也无法打开它)!在这种情况下,打开连接时会抛出一个System.AccessViolationException 下面是代码的外观: string connectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Exten

我有一个将Excel(*.xls)导入数据库的遗留代码,然后在处理后将文件移动到特定目录

该代码工作正常,但有一种情况除外,即文件已损坏(即使MS Excel也无法打开它)!在这种情况下,打开连接时会抛出一个
System.AccessViolationException

下面是代码的外观:

        string connectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""", filePath);
        OleDbConnection connection = new OleDbConnection(connectionString);
        try
        {
            connection.ConnectionString = connectionString;
            connection.Open(); //<<<--- exception throws here
            //file processing
        }
        catch (Exception e)
        {
            //exception handling
        }
        finally
        {
            connection.Close();
            connection.Dispose();
            connection = null;
            GC.Collect();
        }
using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
    using (IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream, true))
    {
        excelReader.IsFirstRowAsColumnNames = true;
        var excelFileDataSet = excelReader.AsDataSet();
        var sheetDataTable = excelFileDataSet.Tables["sheetName"];
        //other file processing code...
    }
}    
如您所见,我正在捕获此异常并对其进行处理,然后当代码尝试将文件移动到另一个目录时,我遇到以下异常:

System.IO.IOException occurred
  Message=The process cannot access the file because it is being used by another process.
  Source=mscorlib
  StackTrace:
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.__Error.WinIOError()
       at System.IO.File.Move(String sourceFileName, String destFileName)
我试图使用另一个库,比如,但发现它内部使用了与我相同的实现,那么它也有同样的问题

我还尝试在连接关闭后运行垃圾收集器(正如您在上面的代码中看到的),但遇到了相同的问题


有什么想法吗?

我现在也有同样的问题,我唯一的解决方案是使用Microsoft.Office.Interop.excel读取excel文件,并设置MsoFileValidationMode=msoFileValidationSkip

Excel.Application xlApp=新的Excel.Application(); Excel.工作簿

        System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
        System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");

        **xlApp.FileValidation = MsoFileValidationMode.msoFileValidationSkip;** 

        xlWorkbook = xlApp.Workbooks.Open(@"C:\my file.xls");
        Excel.Sheets xlWorksheet = xlWorkbook.Worksheets;

        Excel.Worksheet worksheet = (Excel.Worksheet)xlWorksheet.get_Item(3);
        for (int i = 1; i <= 10; i++)
        {

            Excel.Range range = worksheet.get_Range("A" + i.ToString(), "B" + i.ToString()); ; //UsedRange;
            System.Array myvalues = (System.Array)range.Cells.Value2;


            string[] strArray = ConvertToStringArray(myvalues);

            foreach (string item in strArray)
            {   
                MessageBox.Show(item);
            }

        }
System.Globalization.CultureInfo CurrentCI=System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture=新系统.Globalization.CultureInfo(“en-US”);
**xlApp.FileValidation=MsoFileValidationMode.msoFileValidationSkip;**
xlWorkbook=xlApp.Workbooks.Open(@“C:\my file.xls”);
Excel.Sheets xlWorksheet=xlWorkbook.Worksheets;
Excel.Worksheet工作表=(Excel.Worksheet)xlWorksheet.get_项(3);

对于(int i=1;i我试图绕过问题的主要解决方案,但没有结果:(

我甚至检查了.NET Framework代码,可以在代码中的某个地方看到文件句柄,但不幸的是未能调试代码:(

我尝试反编译.NET Framework代码,但也失败了:(

最后,我应该使用另一种解决方案,由于生产机器中不存在MS Office,因此我去了一个开源库,它将*.xls文件读取为二进制流,下面是最终代码的样子:

        string connectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""", filePath);
        OleDbConnection connection = new OleDbConnection(connectionString);
        try
        {
            connection.ConnectionString = connectionString;
            connection.Open(); //<<<--- exception throws here
            //file processing
        }
        catch (Exception e)
        {
            //exception handling
        }
        finally
        {
            connection.Close();
            connection.Dispose();
            connection = null;
            GC.Collect();
        }
using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
    using (IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream, true))
    {
        excelReader.IsFirstRowAsColumnNames = true;
        var excelFileDataSet = excelReader.AsDataSet();
        var sheetDataTable = excelFileDataSet.Tables["sheetName"];
        //other file processing code...
    }
}    

这个解决方案适合我!

似乎Excel应该安装在生产机器上!而且,这个解决方案是否与某些Office版本紧密相关?