Задержка при создании Microsoft.Office.Interop.Word.Application - PullRequest
0 голосов
/ 25 октября 2011

У меня есть (старое 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 возвращает null?

Единственные предлагаемые решения, которые я видел, - это потенциальные бесконечные циклы:

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

Есть ли лучшее решение для этого, чем тупойзадержки или, возможно, бесконечные проверки?

См. также: Ошибка при создании экземпляра Word в VB.net. Та же ошибка, похожий код;но решение состояло в том, чтобы убедиться, что целевой файл существует (что, в моем случае, существует).

1 Ответ

1 голос
/ 25 октября 2011

Я помню, как решал проблемы со связью с занятым COM-сервером out-proc (в моем случае Visual Studio), реализуя интерфейс COM IMessageFilter (который не такой же, какSystem.Windows.Forms.IMessageFilter).

В этой статье MSDN есть * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *. может быть, этот метод поможет.

Кроме того, при автоматизации Office, как вы делаете, вы, скорее всего, столкнетесь с проблемой сбоя Office, , как описано в этом КБarticle .

Чтобы решить эту проблему, нужно быть осторожным, вызывая Marshal.ReleaseComObject для каждого создаваемого вами COM-объекта, предпочтительно в конструкции 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
...