Crystal Reports 8.5 Sections 阻止使用 COM 在 C# 中删除文件

Crystal Reports 8.5 Sections prevents file from being deleted in C# using COM

我创建了一个命令行应用程序,它接受一个 crystal 报告文件,打开它,将其导出到一个文本文件,然后通过删除 crystal 报告自行清理。这工作正常,直到我抑制 crystal 报告中的部分,然后当我尝试删除它时,我得到以下信息:

System.IO.IOException: The process cannot access the file 'C:\ExportCMD\bin\Debug\ReportExportee373f0-e05a-42d6-9b61-9c79e2662c20_636271819978854269.rpt' because it is being used by another process.

经过一些调查,我发现当我在打开的报告中隐藏一个部分时,如果我注释掉该代码,它就可以正常工作。设置Suppress标志的代码是:

private static void SuppressReportSection(ref Report openReport, string sectionToFind, bool hideSection)
    {

        if (!string.IsNullOrWhiteSpace(sectionToFind) && openReport != null)
        {
            openReport.Sections[sectionToFind].Suppress = hideSection;
        }
    }

在检查 Google 解决方案后,我尝试了以下方法:

private static void SuppressReportSection(ref Report openReport, string sectionToFind, bool hideSection)
    {

        if (!string.IsNullOrWhiteSpace(sectionToFind) && openReport != null)
        {

            Sections reportSections = openReport.Sections;

            try
            {
                if (reportSections != null)
                {
                    reportSections[sectionToFind].Suppress = hideSection;
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                if (reportSections != null)
                {
                    Marshal.ReleaseComObject(reportSections);
                    reportSections = null;
                }
            }
        }
    }

不幸的是,这也没有治愈它。我已经尝试过使用和不使用 ref,以防它与报告对象有关。

我不得不使用 Crystal Reports 8.5,我已经添加了参考。 当我销毁我的报告对象时,我调用 Marshal.ReleaseComObject,然后调用 GC.WaitForFullGCComplete(),希望它将释放文件。完成所有这些后,我将调用删除文件的清理代码。清理方法将允许在抛出错误之前多次尝试删除文件。

我哪里错了?如果问题已经有了答案,请指点一下。

我正在使用 C# 和 .Net 4,因为这是我们可以在服务器上获得的最高版本。我无法使用 CrystalDecisions 程序集。

尝试改用 FinalReleaseComObject:

Therefore, use the ReleaseComObject only if it is absolutely required. If you want to call this method to ensure that a COM component is released at a determined time, consider using the FinalReleaseComObject method instead. FinalReleaseComObject will release the underlying COM component regardless of how many times it has re-entered the CLR. The internal reference count of the RCW is incremented by one every time the COM component re-enters the CLR. Therefore, you could call the ReleaseComObject method in a loop until the value returned is zero. This achieves the same result as the FinalReleaseComObject method.

reference

一切都在你的任务管理器中,你所要做的就是..

只需打开 .bat file 使用 task kill 删除 task manager 中的文件。您可以在执行之后或删除报告之前执行此操作。之后您可以自由删除文件或再次打开它而不会出现任何错误。