'The RPC server is unavailable.' when looping through word documents

2

I am working on a utility to find and update DOC VARIABLES in Word. I have a section of code to loop through the documents and present a Message Box with the variable name, but I'm receiving an error when it tries to open the next document. The error is:

System.Runtime.InteropServices.COMException: 'The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)

I'm confused because my code does not access any network. I think what might be happening is the Word is closing when the document closes, but I cannot find a solution to prevent that.

Other things I've tried:

  1. Confirmed UAC is Disabled
  2. Confirmed RPC Services are Running
  3. Confirmed Registry Values for RPC and DCOM are correct

    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
    
vb.net
ms-word
office-interop
asked on Stack Overflow Jul 12, 2019 by Sol_Kralj • edited Jul 12, 2019 by Cindy Meister

2 Answers

2

The RPC error appears when a "pointer" to a COM object is not correctly released from memory before code tries to re-use it. This is a common enough problem when automating Office applications from outside the application, itself. Especially when working from .NET great care must be used.

Another very important thing to note is that the New keyword should never be used with any Office object except Application. Although the APIs allow it, never use New Document with Word as this creates a Document object that can't be correctly released.

For reasons of efficiency, starting the Word application once should be sufficient - it's not necessary to repeat that within a loop, as long as the COM objects it uses are correctly released (set to Nothing and garbage collected).

I would write the code in the question as follows:

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
answered on Stack Overflow Jul 12, 2019 by Cindy Meister
0
'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

The updated code worked when I moved oWord into the loop. Now it creates a new object and quits for each document. I'm not sure if there's a better way.

answered on Stack Overflow Jul 12, 2019 by Sol_Kralj

User contributions licensed under CC BY-SA 3.0