【问题标题】:Error occur during using backgroundworker in ms document C#在 ms 文档 C# 中使用 backgroundworker 时发生错误
【发布时间】:2015-10-24 15:54:09
【问题描述】:

我正在尝试在MS word文档中使用进度条进行循环操作进度,所以我使用backgroundworker在循环操作期间更新进度条,如下代码所示。

  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  using Word = Microsoft.Office.Interop.Word;
  using Microsoft.Office.Tools.Word;

namespace prog
{
public partial class PGB : Form
{
    public PGB()
    {
        InitializeComponent();
    }

    private static int Mx;

    private void PGB_Load(object sender, EventArgs e)
    {
        Mx = 100;

        PG.Maximum = Mx;
        PG.Step = 1;
        PG.Value = 0;
        BGW.RunWorkerAsync();
    }

    private void BGW_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int j = 0; j <= Mx-1; j++)
        {
            Loop_Opt(j+1);
            BGW.ReportProgress((j));
        }
    }

    private void BGW_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        PG.Value = e.ProgressPercentage;
    }

    private void BGW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Done");
    }

    public static void Loop_Opt(int n)
    {
        Word.Application wordApp;
        Word.Document oDoc = null;

        wordApp = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
        oDoc = wordApp.ActiveDocument;
        Document DD = Globals.Factory.GetVstoObject(oDoc);

        for (int i = 1; i <= oDoc.Bookmarks.Count; i++)
        {//loop operation//}
      }
  }
 }

发生错误的行是 Loop_Opt() 类中的以下行:

   Document DD = Globals.Factory.GetVstoObject(oDoc);

错误信息如下:

      [Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.VisualStudio.Tools.Office.Runtime.Interop.IHostItemFactoryNoMAF'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{A0885C0A-33F2-4890-8F29-25C8DE7808F1}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).]

提前致谢

【问题讨论】:

  • 错误出现在哪一行?你试过调试它吗?而且你缺少一些代码?
  • 对不起,我忘了把出现错误的那一行。我会更新的。

标签: c# ms-word ms-office backgroundworker


【解决方案1】:

经过长时间的研究和试验,我认为使用后台工作人员控件没有一个简单的解决方案。

所以我使用普通的方式来更新进度条,而不是如下代码所示的后台工作控件,它可以正常工作,但与后台工作控件的效率不同。

public void Loop_Opt()
{
    Word.Application wordApp;
    Word.Document oDoc = null;

    wordApp = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
    oDoc = wordApp.ActiveDocument;
    Document DD = Globals.Factory.GetVstoObject(oDoc);

    PG.Maximum = oDoc.Bookmarks.Count;
    PG.Step = 1;
    PG.Value = 1;

    for (int i = 1; i <= oDoc.Bookmarks.Count; i++)
    {
       //loop operation//
       PG.PerformStep();
       Thread.Sleep(100);
       Application.DoEvents();
    }
  }

【讨论】:

    【解决方案2】:

    Office 应用程序使用单线程单元模型 (STA)。您不应该在辅助线程上使用它们。此外,Globals.Factory.GetVstoObject 方法只能在基于 VSTO 的插件中使用。

    如果只处理打开的 XML 文档,我建议使用 Open XML SDK。或使用任何其他第三方组件。

    【讨论】:

    • 感谢您的回复,也就是说我不能在办公应用程序中使用多线程?
    • 您只需要在主线程上使用 Office 应用程序。在辅助线程上执行您需要的任何操作,而无需接触 Office 应用程序。
    • 好的,我把进度条更新放在辅助线程上,由主线程更新。但进度条不会以图形方式更新。
    猜你喜欢
    • 1970-01-01
    • 2017-10-16
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多