美好的一天 我的手上有点头疼。 以下代码在我的服务器上运行,它确实适用于它的目的。
public void RenderWithData(string strcaseno, string strdocpath, string strdocsp, string stramnt)
{
Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application[];
string suffix = Convert.ToString(DateTime.Now.Minute + DateTime.Now.Millisecond);
string sourceFileName = System.Web.HttpContext.Current.Server.MapPath(strdocpath);
string destFileName = System.Web.HttpContext.Current.Server.MapPath("~/Cache/" + ActiveLogin.Login + Session.SessionID.ToString + suffix + ".doc");
Word.Document docDepetal = new Word.Document();
FileInfo objFileInfo = default(FileInfo);
try {
File.Copy(sourceFileName, destFileName);
SqlSingleQuery cmd = new SqlSingleQuery(strdocsp);
cmd.AddInt("@USERID", ActiveLogin.UserID);
string ParameterName = "value0";
cmd.AddVarChar(ParameterName, 50, strcaseno);
cmd.AddMoney("@NEWCONSENT", stramnt);
cmd.Execute();
docDepetal = appWord.Documents.Open(destFileName);
Word.Bookmarks MyBookMarks = docDepetal.Bookmarks();
foreach (string bookmark in cmd.Columns.Keys) {
MyBookMarks.Item(bookmark).Range.Text = cmd.Columns.Item(bookmark).ToString();
}
docDepetal.Protect(Word.WdProtectionType.wdAllowOnlyComments, false, "password");
docDepetal.Save();
docDepetal.Close();
appWord.Quit();
Marshal.FinalReleaseComObject(appWord);
appWord = null;
objFileInfo = new FileInfo(destFileName);
DisplayDownloadDialog(objFileInfo);
} catch (Exception ex) {
ShowErrorMsg(ex.Message);
} finally {
if (appWord != null) {
if (docDepetal != null) {
docDepetal.Close();
}
appWord.Quit();
Marshal.FinalReleaseComObject(appWord);
}
if (File.Exists(destFileName)) {
File.Delete(destFileName);
}
}
}
现在我的问题是偶尔winword.exe进程不会在服务器上关闭,之后打开的每个其他winword.exe进程也不会关闭。然后,由于以下错误导致“从iclassfactory创建具有clsid {00020906-0000-0000-c000-000000000046}的com组件的实例失败:8001010a。”每次发送新请求以创建文档时显示的错误。
我想知道在这段代码中我是否可以采用不同的方法来解决这个问题。
请记住,正在创建的文档是在运行时填充的模板,不需要在服务器上进行任何交互。
非常感谢任何帮助,并提前感谢您。
答案 0 :(得分:2)
这很可能是因为你有未创建的COM对象。
我可以看到例如:
MyBookMarks.Item(bookmark).Range.Text = cmd.Columns.Item(bookmark).ToString();
创建许多未关闭的COM对象。因为它们仍处于活动状态,所以winword.exe进程将保持活动状态。
为了确保关闭每个COM对象,必须在创建的每个COM对象上执行此操作:
System.Runtime.InteropServices.Marshal.ReleaseComObject(bookMark);
例如:
// declare below variables...
try
{
bookMark = MyBookMarks.Item(bookmark);
columns = cmd.Columns;
item = columns.Item(bookmark);
range = bookMark.Range;
range.Text = item.ToString();
}
catch (Exception ex)
{
// ...
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(bookMark);
System.Runtime.InteropServices.Marshal.ReleaseComObject(columns);
System.Runtime.InteropServices.Marshal.ReleaseComObject(item);
System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
bookMark = null;
columns = null;
item = null;
range = null;
// A good idea depending on who you talk to...
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
答案 1 :(得分:0)
很抱歉这样说:服务器上的Word不受支持,几乎不是一个好主意。微软强烈反对这种“解决方案”。 如果您必须读/写word文档,我建议使用第三方库或mirosoft open xml。这种方式更稳定,更安全,速度更快(对我而言是100倍)。
如果你绝对想要使用word:实现一个“观察者”线程,它检查单词进程是否真的停止了,如果没有,那么就会对进程造成严重影响。这是一个非常难看的解决方案,但却是强制关闭单词的唯一方法 - 单词中存在错误,这会阻止单词vom一段时间正常关闭。