Хостинг IE 8 в WinForms и открытие PDF-файла
-
03-07-2019 - |
Вопрос
У нас есть форма, в которой размещен элемент управления WebBrowser.Это единственный элемент управления в форме.
Мы передаем форме путь к временному PDF-файлу, и он делает:
WebBrowser1.Navigate(Me._PathToPdf)
Когда форма закрывается, она уходит от PDF-файла:
WebBrowser1.Hide()
WebBrowser1.Navigate("about:blank")
Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
System.Threading.Thread.Sleep(50)
Loop
После закрытия формы вызывающий класс удаляет временный PDF-файл.
Этот процесс работает отлично...пока мы не установили Internet Explorer 8.По какой-то причине комбинация IE8 и Adobe Acrobat 8 (или 9) приводит к тому, что во временный PDF-файл помещается дополнительный дескриптор блокировки файла.Дополнительный дескриптор блокировки не исчезнет, пока все приложение не будет закрыто.Следует также отметить, что файл не блокируется до тех пор, пока он не будет открыт в Acrobat.
Мы можем воспроизвести это на нескольких машинах, и это всегда комбинация IE8 и Adobe Acrobat Reader.Мы можем установить Foxit Reader 3 вместо Adobe Acrobat, и все будет работать нормально.Аналогично, мы можем запустить приложение на компьютере с IE7 и Adobe Acrobat, и все будет работать нормально.Но когда вы смешиваете волшебное зелье IE 8 и Acrobat, вы получаете беспорядок.
Может ли кто-нибудь сказать мне, почему я получаю дополнительную блокировку файлов, которая сохраняется до конца работы приложения?
Спасибо.
Пример приложения, демонстрирующего мою проблему, можно найти здесь: PDFLockProblemDemo.zip
Решение
Мне кажется, настоящие проблемы заключаются в использовании WebBrowser
элемент управления для размещения плагина веб-браузера Adobe Reader для отображения PDF-файлов.Нет ли лучшего способа напрямую отображать PDF-файлы, не прибегая к зависимости от веб-браузера?Разве Adobe не предоставляет SDK или элемент управления ActiveX, который вы можете разместить непосредственно внутри формы?
ОБНОВЛЯТЬ:Я осмотрелся и нашел эта почта где они получают доступ к элементу управления Adobe ActiveX (AxAcroPDFLib.AxAcroPDF
) и просто позвоните:
axAcroPDF1.LoadFile("mypdf.pdf");
axAcroPDF1.Show();
Другие советы
У меня есть ответ, который не потребует никаких временных файлов.
Я был вынужден найти решение, поскольку у меня не было настроения переписывать весь свой код для использования временных файлов.
Итак, вот что вы делаете.
Создайте список строк для хранения файлов для удаления.
Dim filesToDelete As List(Of String) = New List(Of String)
Вам нужно настроить веб-браузер на другой файл PDF,
(Я создал пустой — черный или белый;все, что вам подходит).
Так нравитсяwebbrowser1.navigate("blank.pdf" )
Добавьте файл, который нужно удалить, в список строк.так
filesToDelete.Add(filename)
Вот в чем хитрость.Ресурсы не будут освобождены, пока вы не выйдете из этого события.
Поэтому вам нужно сосредоточиться на чем-то другом, что приведет к запуску другого события.
В моем случае я использовал древовидное представление для просмотра PDF-файла.
Итак, пометив файл на удаление вышеописанным способом,
я бы установил древовидное представление в другой файл.
Итак, вTreeView1_BeforeSelect
метод, я сделал очевидное:
If filesToDelete.Count > 0 Then
For Each f As String In filesToDelete
File.Delete(f)
Next
filesToDelete.Clear()
End If
Вы можете принять свое собственное событие, но я уверен, что после отметки удаления вы сможете найти что-то, что приведет к срабатыванию другого события.Просто следуйте ходу вашего кода и тому, что произойдет дальше.
Итак, вот оно.Надеюсь, это кому-то помогло.
Решение по-прежнему не найдено, но дополнительная информация:Ранее я тестировал XP Pro, Acrobat *.x и .NET 2.0 (созданный с помощью VS 2005).С тех пор я также тестировал различные сценарии, включая Vista, Acrobat 9.x и .NET 3.5 (созданный с помощью VS 2008).
Однако те же результаты:пока используется браузер IE8, PDF-файл не освобождается при вызове Dispose() в элементе управления WebBrowser.Он активируется, когда приложение закрывается, но это нам не помогает...
Надеюсь это поможет.
У нас была такая же проблема с IE8 и Acrobat.В нашем случае нам просто нужно было иметь возможность перезаписать временный PDF-файл и повторно отобразить его.Мы обнаружили, что можем просто открыть PDF-файл, записать 0 байт и закрыть его.После этого мы открывали файл и записывали новую информацию PDF, а затем повторно отображали временный файл.
Подводя итог, мы не решили проблему блокировки файла, вместо этого мы просто оставили прикрепленным дескриптор файла и повторно использовали файл до тех пор, пока пользователь не закроет приложение.
Надеюсь это поможет.