Direct Cast后的C#Interop.Word.Application / Document歧义

时间:2016-01-21 11:41:10

标签: c#

我在这里看到了其他一些有解决方案的问题,但即使是直接转换和垃圾收集也不会消除模糊警告或者阻止我的程序尝试使用显然已经在使用的文档。

以下代码是完全重新命名某些Word文档(更改标题,模板和徽标等)的应用程序的一部分。 MergeDocument没有处理单词application或document(其他方法也需要访问的模板文件)。

WaitForIt方法只是一个2秒的定时器延迟,希望这是访问模板文件的时间问题。在尝试使用try/catch使用的相同模板时,大多数其他方法在GrabLogoFromTemplate MergeDocument被点击之前没有机会做任何事情。

不幸的是它不是,我现在已经没有想法如何解决这个问题,标题中提到的直接投射并没有纠正我认为是Introp Word应用程序和文档关闭的问题。相当的方法。与报告的in this questionhere相同,我尝试了后者中提到的垃圾收集解决方案,但它没有解决我的问题。 Close()和Quit()都不明确,就像第一个问题中的问题一样,但即使处理(我认为我已经正确完成)也不会释放模板以供其他方法使用。

有没有人遇到过这个?

合并按钮:

private void Merge_btn_Click(object sender, EventArgs e)
{
    Rebrand rb = new Rebrand();
    progressBar1.Increment(+1);
    rb.FolderCreation();
    Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();

    progressBar1.Increment(+24);
    string[] fileArray = Directory.GetFiles(currentFolder_tb.Text);

    for (int i=0; i < fileArray.Length; i++)
    {
        string tmpTemplate = rb.GetTempTemplateLocationn(template_tb.Text,i);

        string newDocumentPath = rb.MergeDocument(fileArray[i], newLocation_tb.Text, tmpTemplate, wordApp);
        // ambiguous 
        foreach(Word.Document d in wordApp.Documents)
        {
            d.Close(ref missing, ref missing, ref missing);
        }
        rb.WaitForIt();
        rb.GrabLogoFromTemplate(tmpTemplate);
        rb.WaitForIt();
        if (newDocumentPath != "false")
            rb.ReplaceImageInHeader(newDocumentPath);
    }

    object missing = System.Reflection.Missing.Value;
    ((Microsoft.Office.Interop.Word.Application)wordApp).Quit(ref missing, ref missing, ref missing);
    // the above has ambiguity warning
    GC.Collect();// doesn't solve

    if (progressBar1.Value == 99)
        progressBar1.Increment(+1);
        MessageBox.Show("File(s) ReBranded!");
    progressBar1.Value = 0;
}

合并文档:

public string MergeDocument(string oldDoc, string newDoc, string tmplt, Microsoft.Office.Interop.Word.Application wordApp)
{
    try
    {
        object missing = System.Reflection.Missing.Value;
        //Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
        Microsoft.Office.Interop.Word.Document aDoc = null;
        object readOnly = false;
        object isVisible = false;
        wordApp.Visible = false;
        object oldfile = oldDoc;
        // keep the old document's filename
        object newfile = newDoc + @"\" + Path.GetFileName(oldDoc);
        object template = tmplt;
        // add new template
        aDoc = wordApp.Documents.Add(ref template, ref missing, ref missing, ref missing);
        // open existing document you wish to merge
        aDoc = wordApp.Documents.Open(ref oldfile, ref missing, ref readOnly, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref isVisible,
            ref missing, ref missing, ref missing, ref missing);
        aDoc.Activate();
        aDoc.set_AttachedTemplate(template);
        aDoc.UpdateStyles();
        aDoc.SaveAs(ref newfile, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

        // close the document, ambiguity warning
        ((Microsoft.Office.Interop.Word.Document)aDoc).Close(ref missing, ref missing, ref missing);
        return newfile.ToString();
    }
    catch
    {
        return "false";
    }

}

2 个答案:

答案 0 :(得分:1)

批处理PowerPoint幻灯片时遇到问题。唯一的解决方案是closequit,然后运行GC两次!

  GC.Collect();
  GC.WaitForPendingFinalizers();

  GC.Collect();
  GC.WaitForPendingFinalizers();

答案 1 :(得分:1)

我不完全理解为什么会这样,但这对我来说是解决方案,基本上是两次破坏对象。

过顶,基本上我多次处理同一个对象,但它确实可以解决问题。

模糊性仍然存在,这可能是我需要双击的原因。每个对象。

MergeDocument()位于close()下{I}}我添加了:

if(aDoc != null)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(aDoc);
    aDoc = null;

GrabLogoFromTemplate()之前我添加了一个循环来销毁Document实例中剩余的所有Application类型:

foreach(Word.Document d in wordApp.Documents)
{
    d.Close(ref missing, ref missing, ref missing);
}

最后,就在我调用GC之前,我确保将Application实例设置为null并释放Introp ComObject:

if(wordApp != null)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp);
    wordApp = null;