«Сервер RPC недоступен». при просмотре текстовых документов - PullRequest
0 голосов
/ 12 июля 2019

Я работаю над утилитой для поиска и обновления DOC VARIABLES в Word. У меня есть фрагмент кода для циклического просмотра документов и представления окна сообщений с именем переменной, но я получаю сообщение об ошибке при попытке открыть следующий документ. Ошибка:

System.Runtime.InteropServices.COMException: «Сервер RPC недоступен. (Исключение из HRESULT: 0x800706BA)

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

Другие вещи, которые я пробовал:

  1. Подтверждение UAC отключено
  2. Подтвержденные службы RPC работают
  3. Подтвержденные значения реестра для RPC и DCOM верны

    Private Sub LoopTemp()
        Dim oDir As New DirectoryInfo(dPath)
        Dim oFileArr As FileInfo() = oDir.GetFiles()
        Dim oFile As FileInfo
        Dim oVar As Variable
        Dim oDoc = New Document()
    
        Dim oWord As Application
        oWord = CreateObject("Word.Application")
        oWord.Visible = False
    
        For Each oFile In oFileArr
           oDoc = oWord.Documents.Open(oFile.FullName)
    
           For Each oVar In oDoc.Variables
               MsgBox(oVar.Name)
           Next
    
           oDoc.Close(SaveChanges:=WdSaveOptions.wdSaveChanges)
    
        Next
        oWord.Quit()
    End Sub
    

Ответы [ 2 ]

1 голос
/ 12 июля 2019

Ошибка RPC появляется, когда «указатель» на COM-объект неправильно выводится из памяти, прежде чем код попытается использовать его повторно.Это достаточно распространенная проблема при автоматизации приложений Office вне самого приложения.Особенно при работе с .NET необходимо соблюдать особую осторожность.

Еще одна очень важная вещь, на которую следует обратить внимание, это то, что ключевое слово New никогда не должно использоваться ни с одним объектом Office , кроме Application.Хотя API допускают это, никогда не используйте New Document с Word, поскольку это создает объект Document, который не может быть корректно освобожден.

Из соображений эффективности запускайте приложение Word один раз должно быть достаточно - нет необходимости повторять это в цикле, если используемые им COM-объекты правильно освобождены (установлено значение Nothing и сборка мусора).

Я бы написал код ввопрос следующим образом:

Private Sub LoopTemp()
    Dim oDir As New DirectoryInfo(dPath)
    Dim oFileArr As FileInfo() = oDir.GetFiles()
    Dim oFile As FileInfo
    Dim oVar As Variable = Nothing
    Dim oWord As Application = NOthing
    Dim oDoc As Document = Nothing

    oWord = New Word.Application
    oWord.Visible = False

    For Each oFile In oFileArr
        oDoc = oWord.Documents.Open(oFile.FullName)
        For Each oVar In oDoc.Variables
            MsgBox(oVar.Name)
        Next
        oVar = Nothing
        oDoc.Close(SaveChanges:=WdSaveOptions.wdSaveChanges)
        oDoc = Nothing

        GC.Collect()
        GC.WaitForPendingFinalizers()
        GC.Collect()
        GC.WaitForPendingFinalizers() 
    Next

    oWord.Quit()
    oWord = Nothing
    GC.Collect()
    GC.WaitForPendingFinalizers()
    GC.Collect()
    GC.WaitForPendingFinalizers()

End Sub
0 голосов
/ 12 июля 2019
'Loop through .docx files replacing variables
Private Sub LoopTemp()
    Dim oDir As New DirectoryInfo(dPath)
    Dim oFileArr As FileInfo() = oDir.GetFiles()
    Dim oFile As FileInfo
    Dim oVar As Variable
    Dim oWord As Application

    For Each oFile In oFileArr

        oWord = CreateObject("Word.Application")
        oWord.Visible = False

        GC.Collect()
        GC.WaitForPendingFinalizers()

        Dim oDoc = New Document()
        oDoc = oWord.Documents.Open(oFile.FullName)

        For Each oVar In oDoc.Variables
            MsgBox(oVar.Name)
        Next

        oDoc.Close(SaveChanges:=WdSaveOptions.wdSaveChanges)
        Marshal.FinalReleaseComObject(oDoc)

        oWord.Quit()
        Marshal.FinalReleaseComObject(oWord)

    Next

End Sub

Обновленный код работал, когда я переместил oWord в цикл. Теперь он создает новый объект и выходит для каждого документа. Я не уверен, что есть лучший способ.

...