Winword.exe进程不会在服务器上关闭

时间:2013-11-12 09:28:06

标签: c# office-interop

美好的一天 我的手上有点头疼。 以下代码在我的服务器上运行,它确实适用于它的目的。

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。”每次发送新请求以创建文档时显示的错误。

我想知道在这段代码中我是否可以采用不同的方法来解决这个问题。

请记住,正在创建的文档是在运行时填充的模板,不需要在服务器上进行任何交互。

非常感谢任何帮助,并提前感谢您。

2 个答案:

答案 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一段时间正常关闭。