我们有一个 ASP.Net Web 应用程序 (C#),它通过 Microsoft.Office.Interop.Word 打开 Word 文件。
首先,我意识到这不是推荐的方法,应该考虑使用 TextControl 或 Asppose 等库,我们将考虑用这样的库替换 Microsoft.Office.Interop.Word 的使用。
但是,在短期内,我想让它正常工作,并且我们拥有的代码可以在我的开发机器、客户端的测试服务器上运行,但不能在他们的 UAT 服务器上运行。
客户端的测试服务器和UAT服务器看起来是相同的,我尝试查看各种DCOM配置设置,但没有高兴。
我查看了 Microsoft.Office.Interop.Word 上的其他 Stack Overflow 问题,但没有任何建议有帮助。
为了帮助测试该问题,我编写了一个简单的测试应用程序,尝试使用以下代码打开 Word 文档
var wordApplication = new Application();
var wordDocument = wordApplication.Documents.Open(txtPath.Text);
wordApplication.Visible = true;
运行时,任务管理器中会出现 Word 进程,但会出现以下错误。我显然已经检查了文件权限等。欢迎任何建议。
以下演示项目展示了如何将Word文档文件上传到Web服务器,然后使用
Microsoft.Office.Interop.Word
读取文件。
先决条件:
创建 ASP .NET Web 应用程序
VS 2017:
VS 2019:
注意: 从现在起,VS 2017 和 VS 2019 的过程都是相同的。
添加Web表单:
打开解决方案资源管理器
在解决方案资源管理器中,双击“default3.aspx”。将代码替换为以下内容:
default3.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default3.aspx.cs" Inherits="AspNetWebApp2.Default3" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h3> File Upload:</h3>
<br />
<asp:FileUpload ID="FileUpload1" runat="server" />
<br /><br />
<asp:Button ID="btnsave" runat="server" onclick="btnsave_Click" Text="Save" style="width:85px" />
<br /><br />
<asp:Label ID="lblmessage" runat="server" />
</div>
<div>
<h2>Data:</h2>
<div>
<asp:TextBox ID="textBoxData" runat="server" Height="336px" TextMode="MultiLine" Width="603px"></asp:TextBox>
</div>
</div>
</form>
</body>
</html>
添加引用(Microsoft Word xx.0 对象库)
在解决方案资源管理器中,双击“default3.aspx.cs”并将代码替换为以下内容:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Word = Microsoft.Office.Interop.Word;
namespace AspNetWebApp2
{
public partial class Default3 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnsave_Click(object sender, EventArgs e)
{
bool isVisible = true;
StringBuilder sb = new StringBuilder();
Word.Application wordApp = null;
Word.Document doc = null;
Word.Documents documents = null;
if (FileUpload1.HasFile)
{
try
{
sb.AppendFormat(" Uploading file: {0}", FileUpload1.FileName);
//saving the file
string localDir = System.IO.Path.Combine(Server.MapPath("."), "Uploads");
if (!System.IO.Directory.Exists(localDir))
{
string errMsg = String.Format("<script>alert('Error - Folder does not exist ({0})');</script>", localDir.Replace(@"\",@"\\"));
Response.Write(errMsg);
}
string localFn = System.IO.Path.Combine(Server.MapPath("."), "Uploads", FileUpload1.FileName);
FileUpload1.SaveAs(localFn);
//Showing the file information
sb.AppendFormat("<br/> Save As: {0}", FileUpload1.PostedFile.FileName);
sb.AppendFormat("<br/> File type: {0}", FileUpload1.PostedFile.ContentType);
sb.AppendFormat("<br/> File length: {0}", FileUpload1.PostedFile.ContentLength);
sb.AppendFormat("<br/> File name: {0}", FileUpload1.PostedFile.FileName);
wordApp = new Word.Application();
//suppress displaying alerts (such as prompting to overwrite existing file)
wordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
//set Word visibility
//wordApp.Visible = false;
wordApp.Visible = isVisible;
if (wordApp != null)
{
if (File.Exists(localFn))
{
StringBuilder sbData = new StringBuilder();
doc = wordApp.Documents.Open(localFn, System.Reflection.Missing.Value, false, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, isVisible, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
//doc = documents.Open(localFn);
doc.Activate();
foreach (Word.Paragraph p in doc.Content.Paragraphs)
{
Debug.WriteLine(p.Range.Text);
//Response.Write(p.Range.Text);
sbData.AppendLine(p.Range.Text);
}
textBoxData.Text = sbData.ToString();
}
else
{
Debug.WriteLine("Error: Filename '" + localFn + "' doesn't exist.");
}
}
}
catch (Exception ex)
{
sb.Append("<br/> Error <br/>");
sb.AppendFormat("Unable to save file <br/> {0}", ex.Message);
}
finally
{
if (doc != null)
{
doc.Close();
}
if (documents != null)
{
documents.Close();
}
if (wordApp != null)
{
wordApp.Quit();
wordApp = null;
}
}
}
else
{
lblmessage.Text = sb.ToString();
}
Debug.WriteLine(sb.ToString());
}
}
}
资源:
最终,按照https://stackoverflow.com/a/16481091/1302730上概述的步骤解决了我的问题。
- 我创建了一个新用户(在用户组中),名为 WordUser
- 我已经在IIS中创建了具有WordUser权限的新应用程序池;加载用户资料必须真实
- DCOM 我已设置为使用 WordUser,在“安全”选项卡上我添加了具有启动和激活权限和访问权限的 WordUser
事实证明,本地用户的创建似乎启动了某些操作,即使我将应用程序切换为使用以前的应用程序池,并且将 DCOM 设置切换为使用先前规定的用户,我的应用程序也能正常工作。
将以下软件包安装到您的项目中-
Microsoft.Office.Interop.Word
MicrosoftOfficeCore
如果您使用 COM
Microsoft.Office.Interop.Word
参考,那么它会正常工作。但是当您使用 nuget 参考时,您还需要安装 MicrosoftOfficeCore
包。
现在构建并运行项目。