'The RPC server is unavailable.' 循环遍历 word 文档时
'The RPC server is unavailable.' when looping through word documents
我正在开发一个在 Word 中查找和更新 DOC 变量的实用程序。我有一段代码可以遍历文档并显示一个带有变量名的消息框,但是当它试图打开下一个文档时我收到了一个错误。错误是:
System.Runtime.InteropServices.COMException: 'The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
我很困惑,因为我的代码不访问任何网络。我认为可能发生的情况是文档关闭时 Word 正在关闭,但我找不到防止这种情况发生的解决方案。
我尝试过的其他事情:
- 已确认 UAC 已禁用
- 确认的 RPC 服务是 运行
已确认 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
'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 移入循环时,更新的代码起作用了。现在它创建一个新对象并为每个文档退出。不知道有没有更好的方法。
当 COM 对象的 "pointer" 在代码尝试 re-use 之前未从内存中正确释放时,会出现 RPC 错误。当从应用程序本身外部自动化 Office 应用程序时,这是一个非常常见的问题。尤其是在使用 .NET 时,必须格外小心。
另一个需要注意的非常重要的事情是 New
关键字绝不能与任何 Office 对象一起使用 除了 Application
。尽管 API 允许,但切勿在 Word 中使用 New Document
,因为这会创建无法正确释放的 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
我正在开发一个在 Word 中查找和更新 DOC 变量的实用程序。我有一段代码可以遍历文档并显示一个带有变量名的消息框,但是当它试图打开下一个文档时我收到了一个错误。错误是:
System.Runtime.InteropServices.COMException: 'The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
我很困惑,因为我的代码不访问任何网络。我认为可能发生的情况是文档关闭时 Word 正在关闭,但我找不到防止这种情况发生的解决方案。
我尝试过的其他事情:
- 已确认 UAC 已禁用
- 确认的 RPC 服务是 运行
已确认 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
'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 移入循环时,更新的代码起作用了。现在它创建一个新对象并为每个文档退出。不知道有没有更好的方法。
当 COM 对象的 "pointer" 在代码尝试 re-use 之前未从内存中正确释放时,会出现 RPC 错误。当从应用程序本身外部自动化 Office 应用程序时,这是一个非常常见的问题。尤其是在使用 .NET 时,必须格外小心。
另一个需要注意的非常重要的事情是 New
关键字绝不能与任何 Office 对象一起使用 除了 Application
。尽管 API 允许,但切勿在 Word 中使用 New Document
,因为这会创建无法正确释放的 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