2010-08-04 24 views
8

Tengo un servicio de Windows escrito en C# que lee el texto de documentos de Word (doc y docx) usando VBA Interop. Sin embargo, en ciertos documentos parece que se cuelga de la llamada al método Open. Parece que todos los documentos problemáticos tienen macros. La versión instalada localmente de la palabra tiene macros discapacitados y el código que se utiliza para abrir el documento es el siguiente:Abrir un documento de Microsoft Word en un servicio de Windows parece colgar

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); 

que puede procesar estos documentos manualmente en mi máquina de desarrollo. ¿Alguien sabe por qué está sucediendo esto o tiene más preguntas sobre mi pregunta?

+2

¿La versión de Word en la máquina de producción solicita macros o las desactiva de forma silenciosa? –

+0

¿Qué sucede cuando coloca el código en una aplicación de consola normal y lo ejecuta en la máquina de producción? ¿Aparecerá algún cuadro de diálogo? – Heinzi

+0

Mke - Word debería desactivar silenciosamente las macros. Encontré la clave de registro que corresponde a la opción "deshabilitar todas las macros sin notificación" en el centro de confianza de Word y establecí que para el usuario el servicio se ejecuta pero esto no ha solucionado el problema –

Respuesta

4

He de esperar que finalmente se encontraron todas las cuestiones relativas a esto y han terminado con la siguiente línea para abrir el 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); 

la 4ª y 2ª últimos parámetros impiden que los cuadros de diálogo de reparación y de codificación de la abertura que se corrigió la mayoría de los errores.

La clave de registro para activar desactivar las macros sin notificación es:

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

Finalmente, después de todo lo que todavía había documentos que estaban rompiendo el servicio y fugas casos WinWord. Después de iniciar sesión como usuario del servicio y abrir uno de estos documentos, obtuve este mensaje de diálogo de palabra: "Word no puede iniciar el convertidor mswrd632". Esto se soluciona eliminando una clave de registro como se explica en http://support.microsoft.com/kb/973904.

Editar: También encontré que debido a que VBA no estaba instalado Word abrió un cuadro de diálogo para indicarle al servicio que esto causó que algunos de los documentos cuelguen el servicio. Reinstalarlo y deshabilitarlo a través de Word (como se explicó anteriormente) obtuvo un procesamiento de documentos más. Todavía hay algunos documentos que no se pueden procesar. Pensando en probar http://poi.apache.org/text-extraction.html con ikvmc para analizar los documentos en su lugar.

5

Microsoft.Office.Interop.Word utiliza un contenedor COM para controlar de forma remota el ejecutable de Word real. Es absolutamente horrible. La configuración para deshabilitar macros en la copia de Word que está usando es casi seguro una configuración específica del usuario y el servicio de Windows ejecutará Word como cualquier cuenta de usuario bajo la cual se ejecuta el servicio. Lo más probable es que aparezca esencialmente algún tipo de diálogo de macro seguridad en algún otro mundo teórico que sea el escritorio/usuario de los usuarios de servicios de Windows.

+0

Encontré la clave de registro que corresponde a la opción "deshabilitar todas las macros sin notificación" en el centro de confianza de Word y configuré eso para el usuario que ejecuta el servicio pero esta no es la situación correcta –

2

Existen recomendaciones para la automatización del lado del servidor de Microsoft, pero también hay muchos recursos para ayudarlo si eso es lo que todavía hará. Estos dos artículos deben darle suficiente fondo en lo que a tener en cuenta:

Sin embargo, si es tan simple como sus documentos están colgando debido a cualquier automacros, como AutoOpen , dentro del código VBA detrás, necesitarás usar WordBasic para deshabilitar estos. Nunca podría hacer que esto funcione en C#, pero lo hice en VB.NET. Ver How to open document that contains AutoOpen macro with PowerShell?

Una última opción sería considerar una herramienta que está construida para la automatización de Office del lado del servidor, como Apose.Words.

2

Word indicará al usuario cuando hay un problema menor con el documento. Ese aviso se mostrará en el escritorio para los servicios en su caso, donde nadie puede oírlo gritar. Y evitando que se complete la llamada al método Open().

Asegúrese de establecer el argumento OpenAndRepair del método Open() en True para que se solucione automáticamente sin preguntar al usuario.

+0

Configuré el argumento de apertura y reparación TRUE_VALUE y aún así obtuve el error. La llamada para abrir ahora se ve como 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) –

+0

¿Recibió un error? Eso es bueno, ¿cuál es el error? –

+0

Sí, lamento haber cometido el error cardinal al publicar sobre un error y no haberlo publicado, ¡eh! Ya no la tengo, pero cuando tenga algo de tiempo para tratar de procesar todos los documentos problemáticos, estoy seguro de que la obtendré nuevamente. –

2

También puede intentar llamar al método documents.OpenNoRepairDialog (...). Existe para office 2007 y posterior.

Tenga en cuenta que estoy utilizando llamadas COM rectas, por lo que no estoy seguro de que exista en las librerías de interoperabilidad de la oficina.

+0

El método se encuentra en las DLL de interoperabilidad vsto COM. Tengo el modificador de configuración que puedo usar para permitir que el servicio lo use en lugar del método Open, pero cuando lo usé todavía no pude abrir ninguno de los documentos problemáticos. Por el momento, el servicio funciona lo suficientemente bien sin él, así que no voy a hacer ningún cambio, pero gracias por la sugerencia. –

Cuestiones relacionadas