在 C# 的线程中以编程方式复制 excel 文件时如何修复拒绝访问错误

How to fix access denial error when copying an excel file programmatically within a thread in C#

我正在编写一个程序,该程序将 excel 文件复制到另一个位置并删除可见工作表之外的工作表并保存复制的文件。为了实现这一点,我使用了 BackgroundWorker class。

首先,我初始化了 Background Worker 方法。

private void InitializeBackgroundWorker()
        {
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;
            backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
            backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
        }

"BackgroundWorker.DoWork()"方法如下。

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            GenerateReports(worker);

            // Cancel the asynchronous operation.
            if (worker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

            worker.ReportProgress(100);

            if(backgroundWorker.IsBusy)
            {
                this.backgroundWorker.CancelAsync();
            }
        }

"GenerateReports()"方法包含提取可见工作表的"ExtractVisibleSheets()"方法,然后调用"CopyVisibleSheets()"方法。

private void ExtractVisibleSheets(String originalDirectory, String convertedDirectory)
        {
           //Get the .xlsx files of the original reports and the converted reports
            visibleSheetsOriginal = Directory.GetFiles(originalDirectory, "*.xlsx");
            visibleSheetsConverted = Directory.GetFiles(convertedDirectory, "*.xlsx");

            //Copy the visible sheets to the defined workbooks
            //Sample Reports
            CopyVisibleSheets(originalDirectory, visibleSheetsOriginal, visibleSheetsBasePath);

            //Converted Reports
            CopyVisibleSheets(convertedDirectory, visibleSheetsOriginal, visibleSheetsConvertedPath);                
        }
private void CopyVisibleSheets(String directory, String[] excelFiles, String path)
        {
            excelApplication = null;
            workbook = null;
            Excel.Worksheet sheet = null;
            String copiedReport = "";

            try
            {
                foreach(String report in excelFiles)
                {
                    copiedReport = path + "\" + report.Substring(report.LastIndexOf('\') + 1);

                    excelApplication = GetExcelApplication();

                    File.Copy(report, copiedReport);

                    OpenXmlFileProcessor.RemoveCustomProperty(copiedReport, FileProcessor.BaClientVerParam);

                    workbook = excelApplication.Workbooks.Open(copiedReport);

                    EnableDisableAlertsAndEvents(false);

                    for (int i = workbook.Worksheets.Count; i > 0; i--)
                    {                       
                        sheet = excelApplication.ActiveWorkbook.Worksheets[i];
                        if(sheet.Visible != XlSheetVisibility.xlSheetVisible)
                        {
                            sheet.Visible = XlSheetVisibility.xlSheetVisible;
                            sheet.Delete();                            
                        }                                             
                    }

                    workbook.Save();

                    EnableDisableAlertsAndEvents(true);

                    workbook.Close();

                    Marshal.ReleaseComObject(workbook);
                }                
            }
            finally
            {
                QuitAndReleaseExcelApplication(false);
            }
        }

"BackgroundWorker.RunWorkerCompleted()"方法如下

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // First, handle the case where an exception was thrown.
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                // Next, handle the case where the user cancelled 
                // the operation.
            }
            else
            {
                // Finally, handle the case where the operation 
                // succeeded.                
                MessageBox.Show("Directory Generation Successful!");                    
            }

            EnableControls();
        }

但是在 "File.Copy(report, copiedReport)" 行中出现如下错误,并从 "BackgroundWorker.RunWorkerCompleted()" 方法中触发。

Error

如果有人知道此错误的原因,请告诉我。

path + "\" + report.Substring(report.LastIndexOf('\') + 1);
try to use double qute "" (report.LastIndexOf('\') + 1); 

its a type of strings 
try to use path + "//" + report.Substring(report.LastIndexOf("//") + 1);

如果我错了请纠正我:)

通常,系统C: 驱动器需要管理员权限才能写入。我建议选择另一个驱动器或文件夹(应用程序数据)。