“ RPC服务器不可用。”遍历Word文档时

时间:2019-07-12 01:16:33

标签: vb.net ms-word office-interop

我正在使用一种实用程序来查找和更新Word中的DOC变量。我有一段代码循环浏览文档,并显示一个带有变量名的消息框,但是当它尝试打开下一个文档时出现错误。错误是:

  

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 个答案:

答案 0 :(得分:1)

当代码尝试重新使用COM对象的“指针”未正确从内存中释放时,就会出现RPC错误。从应用程序本身之外自动执行Office应用程序时,这是一个足够普遍的问题。特别是在.NET中工作时,必须格外小心。

要注意的另一个非常重要的事情是,New关键字永远不能与任何Office对象一起使用, Application除外。尽管API允许这样做,但是切勿将New Document与Word一起使用,因为这会创建无法正确释放的Document对象。

出于效率的考虑,一次启动Word应用程序 就足够了-只要正确释放了它使用的COM对象(设置为{{ 1}}并收集垃圾)。

我将在问题中编写代码如下:

Nothing

答案 1 :(得分: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

当我将oWord移入循环时,更新的代码起作用了。现在,它创建一个新对象并为每个文档退出。我不确定是否有更好的方法。