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 doc开发者_如何学Goument
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();
String contents = wordOps.GetContents();
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.
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.
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.
精彩评论