我有一个(传统的VB.Net)应用程序,它从一些表中提取数据,填充一个单词模板,并将该模板与其他几个文件连接起来。
在多台计算机上,这没有任何问题,但是对于一个客户端,在尝试打开模板文件(存在且没有权限问题等)时,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-stop执行的模态对话框,不会抛出异常。
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?
中报告的问题我见过的唯一建议的解决方案是潜在的无限循环:
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.相同的错误,类似的代码;但解决方案是确保目标文件存在(在我的情况下)。
答案 0 :(得分:1)
我记得通过实现the COM IMessageFilter interface(不与{{1}相同)来解决与忙碌的out-proc COM服务器(在我的情况下是Visual Studio)进行通信时遇到的问题})。
this MSDN article中有一个技术示例。
由于Word正忙着启动时出现问题,可能是这种技术会有所帮助。
顺便说一句,当您正在自动执行Office时,您可能会遇到Office无法退出的问题,as described in this KB article。
要解决这个问题,您需要小心在实例化的每个COM对象上调用Marshal.ReleaseComObject,最好是在try / finally构造中。为了确保不会遗漏任何引用,请避免使用“双点”构造System.Windows.Forms.IMessageFilter
,而是显式创建对msWord.Documents的引用。
您的代码看起来应该更像(我猜测VB.NET语法,但您会明白这一点):
msWord.Documents.Add