Разделы Crystal Reports 8.5 предотвращают удаление файла в C# с помощью COM

Я создал приложение командной строки, которое берет файл отчета о кристаллах, открывает его, экспортирует в текстовый файл, а затем очищает себя, удаляя отчет о кристаллах. Это работает нормально, пока я не отключу разделы в кристаллическом отчете, а затем, когда я попытаюсь удалить его, я получаю следующее:

System.IO.IOException: процесс не может получить доступ к файлу «C:\ExportCMD\bin\Debug\ReportExport\2ee373f0-e05a-42d6-9b61-9c79e2662c20\14_636271819978854269.rpt», поскольку он используется другим процессом.

После некоторого расследования я обнаружил, что это происходит, когда я подавляю раздел в открытом отчете, если я закомментирую этот код, он работает нормально. Код для установки флага подавления:

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;
                }
            }
        }
    }

К сожалению, это тоже не вылечило. Я пробовал это с ссылкой и без нее на случай, если это как-то связано с объектом отчета.

Мне приходится использовать Crystal Reports 8.5, и я добавил ссылку. Когда я уничтожаю свой объект отчета, я вызываю Marshal.ReleaseComObject, затем GC.WaitForFullGCComplete() в надежде, что он освободит файл. Как только все это будет завершено, я вызову код очистки, который удалит файлы. Метод очистки позволит несколько раз попытаться удалить файл, прежде чем он выдаст ошибку.

Где я ошибаюсь? Если уже есть ответ на вопрос, можете ли вы указать мне на него, пожалуйста.

Я использую C# с .Net 4, так как это самая высокая версия, которую мы можем получить на серверах. Я не могу использовать сборки CrystalDecisions.


person lardymonkey    schedule 07.04.2017    source источник


Ответы (2)


Вместо этого попробуйте использовать FinalReleaseComObject:

Поэтому используйте ReleaseComObject только в случае крайней необходимости. Если вы хотите вызвать этот метод, чтобы гарантировать выпуск COM-компонента в определенное время, рассмотрите возможность использования вместо этого метода FinalReleaseComObject. FinalReleaseComObject освобождает базовый компонент COM независимо от того, сколько раз он повторно вошел в среду CLR. Внутренний счетчик ссылок RCW увеличивается на единицу каждый раз, когда COM-компонент повторно входит в среду CLR. Таким образом, вы можете вызывать метод ReleaseComObject в цикле до тех пор, пока возвращаемое значение не станет равным нулю. Это дает тот же результат, что и метод FinalReleaseComObject.

ссылка

person heringer    schedule 07.04.2017

Это все еще в вашем диспетчере задач, все, что вам нужно сделать, это...

Просто удалите файл в task manager, используя команду kill, открыв файл .bat file. Вы можете сделать это после выполнения или перед удалением отчета. После этого вы можете свободно удалить файл или открыть его снова без каких-либо ошибок.

person Vijunav Vastivch    schedule 10.04.2017