none
Не закрывается Adobe Acrobat открытый через Visual RRS feed

  • Вопрос

  • Добрый день, помогите закрыть Adobe Acrobat не пойму, что не хватает для закрытия. Вот такой простой код:

    Dim sSourceFile As String = "C:\test.pdf" 
    Dim oAcroPDDoc As Acrobat.AcroPDDoc = New Acrobat.AcroPDDoc
    oAcroPDDoc.Open(sSourceFile)
    oAcroPDDoc.Close()
    oAcroPDDoc = Nothing

    После него в Диспетчере задач остается процесс Acrobat.exe.

    Заранее благодарю.


    • Изменено monteloro 1 июня 2014 г. 15:17
    1 июня 2014 г. 15:15

Ответы

  • Документ не отпускается т.к. объект страницы (AcroPDPage) ссылается на него. Если этот объект "отпустить" (Release), а не просто обнулить, файл можно перемещать.

    Еще раз повторю: Вам не нужно ждать выгрузки процесса Acrobat, нужно лишь вовремя отпускать некоторые интерфейсы (и не обязательно все). Да и сборку мусора можно вручную не делать.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа monteloro 5 июня 2014 г. 13:09
    5 июня 2014 г. 13:01

Все ответы

  • Добрый день.

    Возможно Adobe Acrobat ее корректно отрабатывает команду закрытия во время открытия файлов. Попробуйте для закрытия сделать отдельную кнопку.

    Отвечающий
  • Алексей, добрый день. Не совсем понял Ваше предложение. Я сейчас закрываю Acrobat - Process.GetProcessesByName("Acrobat").First.Kill(), но это не правильно.

    Открытие, обработка PDF  файла и закрытие - это отдельная процедура. После ее вызова файл остается открытым.

  • Смотрите, вы в какой-то момент инициируете работу Adobe Acrobat (по нажатию кнопки в приложении?). В рамках этого метода, вы отправляете команду на закрытие, которая видимо "проглатывается" из-за того, что не закончилось еще открытие файла. Попробуйте отправлять команду на закрытие через несколько секунд после команды открытия файла (например, при нажатии другой кнопки в приложении, для проверки гипотезы).

    Отвечающий
  • Я пробовал, между open и close вставил MsgBox. Но все равно, пауза не помогает.
  • Я не знаю, что за класс AcroPDDoc. Вы добавили ссылку на COM-компонент? Но, судя по названию, он манипулирует документами, а не приложением. Вот, скажем, у MS Word-а есть отдельный компонент документа и компонент приложения. Может, и Acrobat так же?

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    2 июня 2014 г. 16:56
  • Здравствуйте

    Да, конечно я добавляю ссылку на СОМ-компонент, так и называется Acrobat. Оригинальная библиотека, появляется при установки Adobe Acrobat, при установки Adobe Reader ее нет. У меня все работает, я извлекаю текст из PDF  документа. Но только не могу закрыть этот документ.

    Код который я привел он усеченный, но все равно не закрывается.

    Вот ее описание, правда старое: описание Acrobat COM

    Заранее благодарю за помощь.

    2 июня 2014 г. 17:33
  • Ну, как я и предполагал, есть класс App, а у него есть метод Exit. См. страницу 11.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    2 июня 2014 г. 17:43
  • Да, все правильно, есть метод, если сможете помочь применить его, буду признателен, а то я не пойму как ...

    2 июня 2014 г. 17:54
  • Также, как создавали объект PDDoc, создайте объект этого класса. Я не могу точный пример Вам привести, т.к. не знаю, как он называется (посмотрите в обозревателе объектов VS, возможно AcroApp). И в нужный момент вызовите его метод Exit. Думаю, так.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    2 июня 2014 г. 18:02
  • Меня хватило только на такой код, но что-то мне подсказывает, что он не правильный, процесс Acrobat так и остается. Посмотрите, пж

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim AcroApp As New Acrobat.AcroApp
            Dim oAcroPDDoc As Acrobat.AcroPDDoc = New Acrobat.AcroPDDoc
            Dim sSourceFile As String = "C:\Users\Администратор\Desktop\pdfvisual.pdf"
            oAcroPDDoc.Open(sSourceFile)
            oAcroPDDoc.Close()
            oAcroPDDoc = Nothing
            AcroApp.Exit()
        End Sub

    Вот этот код попробовал, открыть приложение и закрыть - все равно процесс остается и не убивается:

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim AcroApp As New Acrobat.AcroApp
            AcroApp.Exit()
            AcroApp = Nothing
        End Sub


    • Изменено monteloro 2 июня 2014 г. 19:16
    2 июня 2014 г. 18:53
  • Я посмотрел на поведение этих классов. Появились такие мысли. Acrobat является локальным сервером COM. Обычно такие серверы не выгружаются мгновенно, т.к. создание нового процесса и его закрытие связано с временными издержками. Даже если все интерфейсы были "отпущены", процесс сервера продолжает некоторое время ждать новых возможных обращений. Сервер гарантировано будет закрыт через несколько секунд после окончания работы Вашего приложения (можете убедиться в этом в Диспетчере задач). Если хотите принудительно его закрыть, нужно инициировать сборку мусора в Вашем приложении:

    GC.Collect()

    Класс AcroApp в таком случае вообще не нужен.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

  • Я проверил, Acrobat весит навечно. Если принудительно закрывать таким кодом, то Acrobat выгружается но через несколько секунд, что не совсем устраивает:

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim oAcroPDDoc As Acrobat.AcroPDDoc = New Acrobat.AcroPDDoc
            If oAcroPDDoc.Open("C:\Users\Администратор\Desktop\Новая папка\tmp.pdf") Then
                oAcroPDDoc.Close()
            End If
            Marshal.FinalReleaseComObject(oAcroPDDoc)
            GC.Collect()
        End Sub


    • Изменено monteloro 3 июня 2014 г. 20:35
    3 июня 2014 г. 19:52
  • Чем не устраивает?

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    3 июня 2014 г. 20:15
  • Кстати, FinalRelease для нулевой ссылки вызывать бессмысленно. Тогда уж не обнуляйте ее.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    3 июня 2014 г. 20:18
  • Скоростью, после

    Process.GetProcessesByName("Acrobat").First.Kill()

    можно сразу обращаться к файлу PDF.

    а после

    Marshal.FinalReleaseComObject(oAcroPDDoc)

    нужно ждать несколько секунд. Так как обрабатывается большое количество PDF файлов, выставлять время System.Threading.Thread.Sleep(2000) это сильно увеличивает общее время обработки.

    3 июня 2014 г. 20:23
  • Спасибо. Конечно, совсем бессмысленно, это от старого кода осталось, пропустил, исправил.
    3 июня 2014 г. 20:32

  • Так как обрабатывается большое количество PDF файлов, выставлять время System.Threading.Thread.Sleep(2000) это сильно увеличивает общее время обработки.

    Тогда стоит ли вообще выгружать сервер? Закрыли один файл, открыли другой. Разве они остаются недоступными после вызова Close?

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    3 июня 2014 г. 20:37
  • Я читаю файл temp.pdf и перемещаю его (File.Move) в папку в зависимости от его содержимого. Но так как он занят Acrobat выдается исключение. Мне не сам Acrobat мешает, а то что он удерживает файл.
    3 июня 2014 г. 20:49
  • Вместо temp.pdf давайте именам уникальные имена (например, Guid). Вместо Move используйте Copy. При выходе из приложения удаляйте все временные файлы.

    Отвечающий
  • После закрытия файла (вызова Close у документа) с ним можно делать все, что угодно (перемещать, удалять и пр.). Проверено (даже при "висящем" процессе Arcobat.exe).


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

  • Алексей, да все верно, спасибо за предложение. Я первоначально так и делал, потом решил упростить алгоритм обработки.
    4 июня 2014 г. 15:59
  • Да, я проверил, тоже работает, если только открыть его и закрыть. Если его и прочесть, то не удается удалить или переместить. Проверьте, пожалуйста, этот код:

    Function readerPDF(sSourceFile As String, Optional ByVal nPage As Integer = 0) As String 'there are two application layer AV for viewing and PD for manipulation Dim oAcroPDDoc As Acrobat.AcroPDDoc = New Acrobat.AcroPDDoc If oAcroPDDoc.Open(sSourceFile) Then Dim acroPDPage As Acrobat.AcroPDPage = Nothing Dim acroHiliteList As New Acrobat.AcroHiliteList acroHiliteList.Add(0, 32767) acroPDPage = oAcroPDDoc.AcquirePage(nPage) Dim strBufer As String = "" 'CreatePageHilite работает с символами; CreateWordHilite работает со словами Dim acroPDTextSel As Acrobat.AcroPDTextSelect = acroPDPage.CreateWordHilite(acroHiliteList) For i As Integer = 0 To acroPDTextSel.GetNumText - 1 strBufer = strBufer & acroPDTextSel.GetText(i).ToString Next acroPDTextSel.Destroy() acroHiliteList = Nothing acroPDPage = Nothing oAcroPDDoc.Close() oAcroPDDoc = Nothing

    Return strBufer Else ' Document FAILED to open. Return vbNullString End If End Function

    но можно закрыть, как Вы советовали через

                Marshal.FinalReleaseComObject(acroHiliteList)
                Marshal.FinalReleaseComObject(acroPDPage)
                Marshal.FinalReleaseComObject(acroPDTextSel)
                Marshal.FinalReleaseComObject(oAcroPDDoc)
                GC.Collect()
    и в этом случае, я проверил, можно сразу удалить или переместить файл, хотя в процессе Acrobat весит секунды две.

           



    • Изменено monteloro 4 июня 2014 г. 16:38
    4 июня 2014 г. 16:30
  • Документ не отпускается т.к. объект страницы (AcroPDPage) ссылается на него. Если этот объект "отпустить" (Release), а не просто обнулить, файл можно перемещать.

    Еще раз повторю: Вам не нужно ждать выгрузки процесса Acrobat, нужно лишь вовремя отпускать некоторые интерфейсы (и не обязательно все). Да и сборку мусора можно вручную не делать.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа monteloro 5 июня 2014 г. 13:09
    5 июня 2014 г. 13:01