问题描述
我有一个(传统VB.Net)应用程序,从某些表中提取数据,填充Word模板,并与其他几个文件模板会连接。
I've got an (legacy VB.Net) application that pulls data from some tables, populates a word template, and concatenates that template with several other files.
在几台机器工作原理没有问题,但对于一个客户端有一个长期存在的问题,其中的话语互操作code抛出未设置为一个对象$ C的一个实例对象引用$ C>试图打开该模板文件(它存在,并且没有权限问题等)。在
On several machines this works with no issues, but for one client there is a persistent problem where the Word Interop code throws Object reference not set to an instance of an object
when attempting to open the template file (which exists, and has no permission issues, etc).
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)
当在(可怕的实现)调试模式抛出了启动正停止执行一堆模式对话框的操作时,没有抛出异常。
When operating in a (horribly implemented) debug mode that throws up a bunch of modal dialogs that starts-n-stops execution, the exception is not thrown.
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)
当运行在正常模式下,有几秒钟的延迟,在没有抛出异常。
When operation in normal mode, with a delay of some seconds, the exception is not thrown.
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需要一些时间来旋转起来。
This suggests that, on some machines, the Word.Application takes some time to "spin up."
但是,对于这个如何最好地捕获,并继续一旦它的存在;或者如果时限是淫秽抛出一个错误(一如既往,最好由地方管辖决定)?
这也是在MSDN论坛报告人的问题@ WordApplication.Documents.Add方法返回NULL?
This is also an issue reported by others in the MSDN forums @ WordApplication.Documents.Add Method return null?
我见过的唯一建议的解决方案是潜在的无限循环:
The only suggested solutions I've seen are potential infinite loops:
Document nulldoc = null;
do
{
document = application.Documents.Add(template, newtemplate, documenttype, visible);
Thread.Sleep(100);
}
while (document == nulldoc);
有这个更好的解决办法比哑延误,或可能无限检查循环?
另请参见:Error创建的Word在VB.net实例时的相同错误,类似code。但解决的办法是要确保目标文件存在(这不,在我的情况)。
See Also: Error when creating an instance of Word in VB.net. Same error, similar code; but the solution was to ensure that the target file existed (which does, in my case).
推荐答案
我记得解决问题的一个繁忙的出进程内COM服务器(在我的情况下,Visual Studio中)进行通信,通过实施的的COM IMessageFilter接口(即不一样的 System.Windows.Forms.IMessageFilter
)。
I remember solving problems with communicating with a busy out-proc COM server (Visual Studio in my case), by implementing the COM IMessageFilter interface (which is not the same as System.Windows.Forms.IMessageFilter
).
有技术的这个MSDN的例子文章。
由于您的问题发生在Word中忙启动,它的可以的是,这种技术将有助于。
Since your problem happens when Word is busy starting up, it may be that this technique will help.
顺便说一句,当办公自动化,你在做什么,你很可能会遇到的Office失败退出,的描述。
As an aside, when automating Office as you are doing, you are likely to come across the problem of Office failing to quit, as described in this KB article.
要解决这个问题,你必须要小心调用Marshal.ReleaseComObject的实例化每一个COM对象,$ P $上pferably在try / finally结构。为了确保您不会错过任何引用,避免了双点建设 msWord.Documents.Add
,而是明确地创建一个引用msWord.Documents。
To solve this, you need to be careful to call Marshal.ReleaseComObject on every COM object you instantiate, preferably in a try/finally construct. To make sure you don't miss any references, avoid the "double-dot" construct msWord.Documents.Add
, and instead explicitly create a reference to msWord.Documents.
您code应该看起来更像是(我猜的VB.NET的语法,但你的想法):
Your code should look more like (I'm guessing the VB.NET syntax, but you'll get the idea):
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
这篇关于延迟创建Microsoft.Office.Interop.Word.Application时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!