1

大家好,我的手上有点挠头。以下代码在我的服务器上运行,并且可以按预期工作。

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

我想知道我是否可以在这段代码中做一些不同的事情来解决这个问题。

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

非常感谢您的任何帮助,并在此先感谢您。

4

2 回答 2

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();
}
于 2013-11-12T09:43:17.110 回答
0

很抱歉地说:服务器上的 Word 不受支持,几乎从来都不是一个好主意。微软强烈反对这种“解决方案”。如果您必须读/写 word 文档,我建议您使用第三方库或 mirosoft open xml。这是更稳定、更安全且速度更快的方式(对我来说是 100 倍)。

如果您绝对想使用 word:实现一个“观察者”线程,它检查 word 进程是否真的停止了,如果没有,则对进程进行硬杀。这是一个极其丑陋的解决方案,但却是强制关闭单词的唯一方法 - 单词中存在错误,这些错误会阻止单词 vom 偶尔正确关闭。

于 2013-11-12T09:37:23.530 回答