ASP.NET 代码仅适用于本地计算机

发布于 2024-10-12 10:57:02 字数 3067 浏览 3 评论 0原文

我在设置 ASP.NET 网站时遇到了一些问题,而且很难调试。

背景信息:

我的网站上有一个页面,允许用户上传一个或多个 Microsoft Word 文档。然后,用户可以按下按钮,代码应该打开文档,计算单词数,然后返回表中的单词数。

当我在 Visual Studio 中运行调试器时,这工作得很好,但是当我尝试从另一台计算机通过网络执行此操作时,我收到错误。

这是一些代码。我试图尽可能地简化它。

// List of int's to hold the number of words in each document
List<int> words = new List<int>();

// Loop through the files that the user selected
// (The files have already been uploaded, and now their path is in "lstFileBox")
for (int i = 0; i < this.lstFileBox.Items.Count; i++)
{
    try
    {
         String file = this.lstFileBox.Items[i].Text;
         // MicrosoftWordOperations is a custom class
         MicrosoftWordOperations wordOps = new MicrosoftWordOperations(file);
         String contents = wordOps.GetContents();
         int numWords = wordOps.CountWords(contents);

          // Add number of words to my list
          words.Add(numWords);

          // Delete the uploaded file, which was stored in a temporary location
          if (System.IO.File.Exists(file))
               System.IO.File.Delete(file);

          }
          catch (Exception e)
          {

          }
      }

      // ...
      // Then add number of words to a table
      // ...

MicrosoftWordOperations 代码非常基本:

public class MicrosoftWordOperations
{
    private String _file;

    public MicrosoftWordOperations(String file)
    {
        this._file = file;
    }

    public String GetContents()
    {
        object fileName = (object)this._file;
        object missing = System.Reflection.Missing.Value;

        Word.Application wordObject = new Word.Application();
        Word.Document wordDocument = wordObject.Documents.Open(
            ref fileName, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing);
        Word.Document activeDocument = wordObject.ActiveDocument;
        String fileContents = activeDocument.Content.Text;
        wordDocument.Close(ref missing, ref missing, ref missing);

        return fileContents;
    }

    public int CountWords(String text)
    {
        MatchCollection collection = Regex.Matches(text, @"[\S]+");
        return collection.Count;
    }
}

编辑:

我能够进行一些基本的调试,这是在第一个代码块中捕获的异常:

System.UnauthorizedAccessException:检索 COM 类工厂 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败 由于以下错误:80070005 访问被拒绝。 (例外情况来自 HRESULT:0x80070005(E_ACCESSDENIED))。在 MicrosoftWordOperations.GetContents() 中 [路径]\MicrosoftWordOperations.cs:第 26 行位于 [路径]\WordCounter.aspx.cs 中的 Content_WordCounter.CountWords():第 69 行

编辑:

MSWord 安装在服务器上。

编辑:

第26行:Word.Application wordObject = new Word.Application();
第 69 行:String content = wordOps.GetContents();

I am having some trouble with an ASP.NET website I've set up and it's very difficult to debug.

Background Information:

There is a page on my website that allows the user to upload one or many Microsoft Word documents. The user can then press a button, and the code is supposed to open the document(s), count the words, and then return the number of words in a table.

This works perfectly fine when I am in Visual Studio running the debugger, however when I try to do it over the web from another computer, I get an error.

Here is some code. I tried to simplify it as much as possible.

// List of int's to hold the number of words in each document
List<int> words = new List<int>();

// Loop through the files that the user selected
// (The files have already been uploaded, and now their path is in "lstFileBox")
for (int i = 0; i < this.lstFileBox.Items.Count; i++)
{
    try
    {
         String file = this.lstFileBox.Items[i].Text;
         // MicrosoftWordOperations is a custom class
         MicrosoftWordOperations wordOps = new MicrosoftWordOperations(file);
         String contents = wordOps.GetContents();
         int numWords = wordOps.CountWords(contents);

          // Add number of words to my list
          words.Add(numWords);

          // Delete the uploaded file, which was stored in a temporary location
          if (System.IO.File.Exists(file))
               System.IO.File.Delete(file);

          }
          catch (Exception e)
          {

          }
      }

      // ...
      // Then add number of words to a table
      // ...

And the MicrosoftWordOperations code is pretty basic:

public class MicrosoftWordOperations
{
    private String _file;

    public MicrosoftWordOperations(String file)
    {
        this._file = file;
    }

    public String GetContents()
    {
        object fileName = (object)this._file;
        object missing = System.Reflection.Missing.Value;

        Word.Application wordObject = new Word.Application();
        Word.Document wordDocument = wordObject.Documents.Open(
            ref fileName, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing);
        Word.Document activeDocument = wordObject.ActiveDocument;
        String fileContents = activeDocument.Content.Text;
        wordDocument.Close(ref missing, ref missing, ref missing);

        return fileContents;
    }

    public int CountWords(String text)
    {
        MatchCollection collection = Regex.Matches(text, @"[\S]+");
        return collection.Count;
    }
}

Edit:

I was able to do some basic debugging, and here is the Exception that gets caught in the first code block:

System.UnauthorizedAccessException: Retrieving the COM class factory
for component with CLSID {000209FF-0000-0000-C000-000000000046} failed
due to the following error: 80070005 Access is denied. (Exception from
HRESULT: 0x80070005 (E_ACCESSDENIED)). at
MicrosoftWordOperations.GetContents() in
[path]\MicrosoftWordOperations.cs:line 26 at
Content_WordCounter.CountWords() in [path]\WordCounter.aspx.cs:line 69

Edit:

MSWord is installed on the server.

Edit:

Line 26: Word.Application wordObject = new Word.Application();
Line 69: String contents = wordOps.GetContents();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橘寄 2024-10-19 10:57:02

引用 Microsoft MSKB 257757

Microsoft 目前不建议也不支持通过任何无人值守、非交互式客户端应用程序或组件(包括 ASP、ASP.NET、DCOM 和 NT 服务)实现 Microsoft Office 应用程序的自动化,因为 Office 可能会表现出不稳定的情况Office 在此环境中运行时的行为和/或死锁。

所以,你不应该这样做。也就是说,让我们尝试解决您的问题。 Word 是否安装在 Web 服务器上?如果没有:您需要安装它。如果是,请告诉我们 MicrosoftWordOperations.cs 的哪一行是第 26 行(错误消息中提到的那一行)。

编辑:由于第 26 行是 Word.Application 的创建,因此运行 Web 应用程序的用户帐户可能没有启动 Word 所需的权限。为了验证这一假设,我建议您在服务器上的“常规”用户帐户下运行 Web 应用程序(例如,使用 标记(位于 web.config 中)。让我再次引用上面链接的知识库文章:

用户身份:Office 应用程序在运行时假定用户身份,即使自动化启动应用程序时也是如此。应用程序尝试根据启动应用程序的用户的用户注册表配置单元中的设置来初始化工具栏、菜单、选项、打印机和一些加载项。许多服务在没有用户配置文件的帐户(例如 SYSTEM 帐户或 IWAM_[servername] 帐户)下运行。因此,Office 在启动时可能无法正确初始化。在这种情况下,Office 在 CreateObject 函数或 CoCreateInstance 函数上返回错误。即使 Office 应用程序可以启动,如果不存在用户配置文件,其他功能也可能无法正常工作。

因此,您的 Web 应用程序需要在具有用户配置文件的 Windows 帐户下运行。

To quote Microsoft MSKB 257757:

Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.

So, you shouldn't do it. That said, let's try to fix your problem. Is Word installed on the Web Server? If no: You need to install it. If yes, please tell us which line of MicrosoftWordOperations.cs is line 26 (the one mentioned in the error message).

EDIT: Since line 26 is the creation of Word.Application, the user account running your web application might not have the necessary permissions to start Word. To verify this assumption, I would suggest that you run your web application under the account of a "regular" user on your server (using, for example, the <identity ...> tag in your web.config). Let me quote again from the KB article linked above:

User Identity: Office applications assume a user identity when the applications are run, even when Automation starts the applications. The applications try to initialize toolbars, menus, options, printers, and some add-ins based on settings in the user registry hive for the user who launches the application. Many services run under accounts that have no user profiles (such as the SYSTEM account or the IWAM_[servername] accounts). Therefore, Office may not initialize correctly on startup. In this situation, Office returns an error on the CreateObject function or the CoCreateInstance function. Even if the Office application can be started, other functions may not work correctly if no user profile exists.

So, your web application needs to run under a Windows account that has a user profile.

伪心 2024-10-19 10:57:02

正如其他人所说,在服务器上自动化 Word 不是一个好主意。您是否考虑过替代解决方案?

如果您只能使用 openxml 格式 (.docx),则 OpenXml SDK 是一个更好的选择。如果您必须以较旧的 .doc 格式生成文档,我建议您查看像 Aspose 这样的第 3 方组件,尽管这显然不是免费的解决方案。

As others have said, it's a bad idea to automate Word on the server. Have you considered alternative solutions?

If you can use the openxml format (.docx) exclusively, the OpenXml SDK is a better alternative. If you must generate the documents in the older .doc format, I would advise to look at a 3rd party component like Aspose, though that is obviously not a free solution.

挖鼻大婶 2024-10-19 10:57:02

除非该远程服务安装了 Microsoft Word,否则您不能依赖该代码。该代码在运行服务器端代码的计算机上使用 COM 自动化。

Unless that remote service has Microsoft Word installed, you can't rely on that code. The code is using COM automation on the machine on which your server side code is running.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文