【问题标题】:Delay when creating Microsoft.Office.Interop.Word.Application创建 Microsoft.Office.Interop.Word.Application 时出现延迟
【发布时间】:2023-03-11 10:52:01
【问题描述】:

我有一个(旧版 VB.Net)应用程序,它从一些表中提取数据,填充一个 word 模板,并将该模板与其他几个文件连接起来。

在几台机器上这可以正常工作,但对于一个客户端来说,在尝试打开模板文件(存在,并且没有权限问题等)时,Word Interop 代码会抛出Object reference not set to an instance of an object 的持久性问题。

Dim doc As Document
Dim msWord As Microsoft.Office.Interop.Word.Application

msWord = New Microsoft.Office.Interop.Word.Application
' next line throws "Object reference not set to an instance of an object"
doc = msWord.Documents.Add(verifiedTemplateName)

在(可怕地实现的)调试模式下运行时,会抛出一堆启动-n-停止执行的模式对话框,不会抛出异常。

Dim doc As Document
Dim msWord As Microsoft.Office.Interop.Word.Application

msWord = New Microsoft.Office.Interop.Word.Application
MsgBox("VooDoo coder at work")
' now no exception is thrown
doc = msWord.Documents.Add(verifiedTemplateName)

在正常模式下运行时,延迟几秒,不抛出异常。

Dim doc As Document
Dim msWord As Microsoft.Office.Interop.Word.Application

msWord = New Microsoft.Office.Interop.Word.Application
Delay(5) ' function that pauses for one second
' now no exception is thrown
doc = msWord.Documents.Add(verifiedTemplateName)

这表明,在某些机器上,Word.Application 需要一些时间才能“启动”。

但是如何最好地捕捉到这一点,并在它存在时继续;或者如果时间框架是淫秽的(一如既往,最好由当地管辖区决定)抛出错误?

这也是其他人在MSDN论坛@WordApplication.Documents.Add Method return null?WordApplication.Documents.Add Method return null?报告的问题

我见过的唯一建议的解决方案是潜在的无限循环:

Document nulldoc = null;
do
{
    document = application.Documents.Add(template, newtemplate, documenttype, visible);
    Thread.Sleep(100);
}
while (document == nulldoc);

有没有比愚蠢的延迟或可能无限的检查循环更好的解决方案?

另见:Error when creating an instance of Word in VB.net. 同样的错误,类似的代码;但解决方案是确保目标文件存在(在我的情况下确实存在)。

【问题讨论】:

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


    【解决方案1】:

    我记得通过实现the COM IMessageFilter interfaceSystem.Windows.Forms.IMessageFilter相同)解决了与繁忙的out-proc COM服务器(在我的情况下为Visual Studio)通信的问题。

    this MSDN article 中有一个技术示例。

    由于您的问题发生在 Word 忙于启动时,可能这种技术会有所帮助。

    顺便说一句,在自动化 Office 时,您可能会遇到 Office 无法退出的问题,as described in this KB article

    要解决这个问题,您需要小心地在您实例化的每个 COM 对象上调用 Marshal.ReleaseComObject,最好是在 try/finally 构造中。为确保不会遗漏任何引用,请避免使用“双点”构造 msWord.Documents.Add,而是显式创建对 msWord.Documents 的引用。

    您的代码应该看起来更像(我猜是 VB.NET 语法,但您会明白的):

    Dim msWord As Application
    Dim doc As Document
    Dim docs As Documents
    
    Try
        msWord = ...
        docs = msWord.Documents
        ' Test if docs is Nothing to avoid a NullReferenceException
        If Not docs Is Nothing Then
            doc = docs.Add...
            ...
        End If
        ...
    Finally
        If Not doc Is Nothing Then Marshal.ReleaseComObject doc
        If Not docs Is Nothing Then Marshal.ReleaseComObject docs
        If Not msWord Is Nothing Then 
            msWord.Quit
            Marshal.ReleaseComObject msWord
        End If
    End Try
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    相关资源
    最近更新 更多