C# 在Windows服务中打开Microsoft Word文档似乎挂起

C# 在Windows服务中打开Microsoft Word文档似乎挂起,c#,windows-services,interop,ms-word,C#,Windows Services,Interop,Ms Word,我有一个用c#编写的windows服务,它使用VBA互操作从word文档(doc和docx)读取文本。然而,在某些文档上,它似乎挂起了对Open方法的调用。问题文档中似乎都有宏。本地安装的word版本已禁用宏,我用于打开文档的代码如下: using Word = Microsoft.Office.Interop.Word; using OfficeCore = Microsoft.Office.Core; Word.Application m_wordApp = new Word.Applic

我有一个用c#编写的windows服务,它使用VBA互操作从word文档(doc和docx)读取文本。然而,在某些文档上,它似乎挂起了对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);

我可以在我的开发机器上手动处理这些文档。有人知道为什么会发生这种情况,或者对我的问题有任何进一步的疑问吗?

Microsoft.Office.Interop.Word
使用COM包装器远程控制实际的Word可执行文件。这是绝对不可能的。禁用其使用的Word副本中的宏的设置几乎肯定是用户特定的设置,Windows服务将以运行该服务的任何用户帐户的形式运行Word。很有可能它实际上是在一些理论上的阴暗世界中弹出某种宏安全对话框,即Windows服务用户桌面/ui。

有一些建议反对Microsoft的服务器端自动化,但如果您仍然要这样做,也有很多资源可以帮助您。这两篇文章应为您提供充分的背景知识,以解释:

但是,如果由于VBA代码中的任何自动宏(如
AutoOpen
)而导致文档挂起,那么您需要使用WordBasic来禁用这些宏。我永远无法在C#中实现这一点,但我在VB.NET中做到了。看


最后一个选项是考虑一个为服务器端办公自动化构建的工具,如

Word将在文档存在一个小问题时提示用户。该提示将显示在您的服务桌面上,没有人能听到它的尖叫声。并阻止Open()方法调用完成


请确保将Open()方法的OpenAndRepair参数设置为True,以便在不提示用户的情况下自动处理此问题。

我希望最终找到与此相关的所有问题,并以以下行结束打开文档:

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\12.0\Word\Security]
"VBAWarnings"=dword:00000004
最后,尽管如此,仍然有一些文档正在破坏服务并泄漏winword实例。在以服务用户身份登录并打开其中一个文档后,我从word获得了一个消息对话框:“word无法启动转换器mswrd632”。如中所述,通过删除注册表项可以解决此问题


编辑:我还发现,由于没有安装VBA,Word打开了一个对话框告诉服务这一点,这导致一些文档挂起了服务。重新安装它,然后禁用,尽管Word本身(如上所述)得到了更多的文档处理。还有一些文档无法处理。考虑使用ikvmc来解析文档。

您也可以尝试调用documents.OpenNoRepairDialog(…)方法。它适用于Office2007及更高版本


请注意,我使用的是直接COM调用,因此我不确定它是否存在于office interop libs中。

生产机器上的Word版本是否会提示输入宏,或以静默方式禁用宏?将代码放入常规控制台应用程序并在生产机器上执行时会发生什么?是否会弹出一些对话框?Mke-Word应该以静默方式禁用宏。我在Word trust Center中找到了与“禁用所有宏而不通知”选项相对应的注册表项,并将该注册表项设置为服务运行时的状态,但这并没有解决问题。我只是想继续查看下面的内容是否回答了您的问题。我将“打开并修复”参数设置为TRUE\u值,但仍然得到了错误。现在调用open看起来像m_wordApp.Documents.open(ref fileNameObject、ref FALSE_值、ref TRUE_值、ref MISSING_值、ref MISSING_值、ref MISSING_值、ref MISSING_值、ref MISSING_值、ref MISSING_值、ref FALSE_值、ref TRUE_值、ref MISSING_值)是,抱歉,在发布关于错误的信息时犯了主要错误,但没有发布,d'uh!我已经没有了,但当我有时间尝试处理所有有问题的文档时,我确信我会再次得到它。我找到了对应于“禁用所有宏而不通知”的注册表项选项,并为用户设置服务运行方式,但这不正确。该方法位于vsto COM互操作DLL中。我确实有配置开关,我可以使用它来让服务使用它而不是Open方法,但是使用它时,我仍然无法打开任何有问题的文档。目前,没有它,服务运行得很好,所以我不打算做任何更改,但感谢您的建议。