Открытие документа Microsoft Word в службе Windows подвисает

У меня есть служба windows, написанная на c#, которая читает текст из документов word (doc и docx) с помощью VBA Interop. Однако на некоторых документах он, похоже, зависает при вызове метода Open. Кажется, что во всех проблемных документах есть макросы. Локально установленной версии Word макросов и кода, который я использую для открытия документа выглядит следующим образом:

using Word = Microsoft.Office.Interop.Word;
using OfficeCore = Microsoft.Office.Core;

Word.Application m_wordApp = new Word.ApplicationClass();
Word.Document m_wordDoc = null;

object TRUE_VALUE = true;
object FALSE_VALUE = false;
object MISSING_VALUE = System.Reflection.Missing.Value;

m_wordApp.DisplayAlerts = Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone; //will still fail with this line removed
m_wordApp.Visible = false; //will still fail with this line removed
m_wordApp.AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityForceDisable; //will still fail with this line removed
m_wordDoc = m_wordApp.Documents.Open(ref fileNameObject, ref FALSE_VALUE, ref TRUE_VALUE, ref FALSE_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref FALSE_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE);

Я могу обрабатывать эти документы вручную на мое развитие машины. Кто-нибудь знает почему это происходит или есть какие-либо дополнительные вопросы по моему вопросу?

5 ответов


Microsoft.Office.Interop.Word использует com-оболочку для удаленного управления исполняемым файлом Word. Это абсолютно ужасно. Параметр для отключения макросов в копии Word, который он использует, почти наверняка является пользовательским параметром, и служба Windows будет запускать Word как любую учетную запись пользователя, под которой работает служба. Скорее всего, это по существу выскакивает какой-то диалог безопасности макросов в какой-то теоретической преисподней, которая является Windows Service users desktop/ui.


Я надеюсь, наконец-то нашел все проблемы, связанные с этим, и закончил со следующей строкой, чтобы открыть doc:

m_wordApp.Documents.Open(ref fileNameObject, ref FALSE_VALUE, ref TRUE_VALUE, ref FALSE_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref MISSING_VALUE, ref FALSE_VALUE, ref TRUE_VALUE, ref MISSING_VALUE, ref TRUE_VALUE, ref MISSING_VALUE);

4-й и 2-й последние параметры предотвращают открытие диалогов восстановления и кодирования, которые исправили большинство ошибок.

раздел реестра, чтобы включить отключить макросы без уведомления:

[HKEY_USERS\S-x-x-xx-xxxxxxxxxx-xxxxxxxxx-xxxxxxxxxx-xxx\Software\Microsoft\Office.0\Word\Security]
"VBAWarnings"=dword:00000004

наконец, после всего этого все еще были документы, которые сбой службы и утечка экземпляров winword. После войдя в систему как пользователь сервиса и открыв один из этих документов, я получил это диалоговое окно сообщения от word: "Word не может запустить конвертер mswrd632". Это исправлено путем удаления раздела реестра, как описано в http://support.microsoft.com/kb/973904.

Edit: я также обнаружил, что, поскольку VBA не был установлен, Word открыл диалоговое окно, чтобы сообщить Службе об этом, что заставило некоторые документы повесить службу. Переустановка его затем отключение, хотя само слово (как объяснено выше) получил еще несколько документов. Еще несколько документов, которые не могут быть обработаны. Думал о попытке http://poi.apache.org/text-extraction.html с ikvmc вместо разбора документов.


есть рекомендации от серверной автоматизации от Microsoft, но есть также много ресурсов, чтобы помочь вам, если это то, что вы еще собираетесь делать. Эти две статьи должны дать вам достаточную информацию о том, что нужно учитывать:

однако, если это так просто, как ваши документы висят из-за любых AutoMacros, как AutoOpen, внутри кода VBA позади, вам нужно будет использовать WordBasic, чтобы отключить их. Я никогда не мог заставить это работать на C#, но я сделал это в VB.NET - ... См.как открыть документ, содержащий макрос AutoOpen с помощью PowerShell?

последним вариантом было бы рассмотреть инструмент, который построен для автоматизации Office на стороне сервера, например Apose.Слова!--6-->.


Word предложит пользователю, когда есть небольшая проблема с документом. Это приглашение будет отображаться на рабочем столе для служб в вашем случае, где никто не может услышать его крик. И предотвращение завершения вызова метода Open ().

обязательно установите аргумент OpenAndRepair метода Open () в значение True, чтобы это обрабатывалось автоматически без запроса пользователя.


вы также можете попробовать вызвать документы.OpenNoRepairDialog(...) метод. Он существует для office 2007 и более поздних версий.

обратите внимание, что я использую прямые COM-вызовы, поэтому я не уверен, что он существует в библиотеках office interop.