无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类型“Microsoft.VisualStudio.Tools.Applications.Runtime.IHostS...

先看问题:

无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类型“Microsoft.VisualStudio.Tools.Applications.Runtime.IHostServiceProvider”。此操作失败的原因是对 IID 为“{D80D8C20-D524-47ED-A9DD-FA05472F7C64}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 不支持此接口 (异常来自 HRESULT:0x80004002 (E_NOINTERFACE))。


   在 Microsoft.VisualStudio.Tools.Applications.Runtime.IHostServiceProvider.GetService(Type serviceType)
   在 Microsoft.VisualStudio.Tools.Applications.Runtime.AppDomainManagerInternal.GetService(Type serviceType)
   在 Microsoft.Office.Tools.ActionsPaneInternal.HookupSmartPane()
   在 Microsoft.Office.Tools.DockableControlCollection.Add(Control value)
   在 kfky_jsyz_xmjis_mb.frmProcessBar.InitData() 位置 E:\New Work Files\HNKFModels\kfky_jsyz_xmjis_mb\frmProcessBar.cs:行号 35
   在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ThreadHelper.ThreadStart()

问题描述:

近来由于项目需求,我接触了VSTO,上述问题就是在项目中加载ActionPanel控件中出现的,以下是加载ActionPanel的方法

         public   void  InitActionPanel()
ExpandedBlockStart.gif       
{
            ActionsPaneControl customControl 
= new ActionsPaneControl(this);
            ActionsPane.Controls.Add(customControl);
        }

 

如果把这个方法直接放到ThisDocument_Startup方法中执行没有任何问题,ActionPanel可以正常加载出来,可是由于这个ActionPanel在实例化的时候执行了复杂的操作,所以我想把该方法放到新的线程中去执行,因此导致了上述错误

想了好多办法都不行,后来在MSDN上找到类似的博文,http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/a4ca779c-ae74-48db-9fb8-efaaa6edd3aa/
看了一下,原因应该是跨线程操作控件的问题,毕竟发帖人已经把问题解决了,然后我看了一下我的代码,进行了如下修改,终于不再报错,下面提供一下解决思路:

在运用多线程操作控件的时候,经常会看到一句话:控件只能由创建它的线程去处理该控件。通俗的说就是控件由那个线程创建就应该由那个线程去处理,再看一下我的方法,因为ActionPanel对象是在主线程(文档的启动线程)创建的,如果我把上述方法写到一个新线程中,肯定不能像平常一样使用它的Controls.Add方法了,因为这相当于从新起的线程中去操作主线程创建的控件,所以此时应该想到使用委托,把Add方法委托给主线程,于是应该有以下代码:

 

frmProcessBar frmPB  =   null ; // 提示性窗体显示“正在加载”
public   delegate   void  AddControl(Control control); // 声明Controls.Add方法的委托

// 文档启动方法,该方法在主线程中创建
private   void  ThisDocument_Startup( object  sender, System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif
{
   frmPB 
= new frmProcessBar();
   frmPB.Show();
   
//创建新线程去执行InitActionPanel方法
   Thread workThread = new Thread(new ThreadStart(InitActionPanel));
   workThread.SetApartmentState(ApartmentState.STA);
   workThread.IsBackground 
= true;
   workThread.Start();
}


public   void  InitActionPanel(ActionsPaneControl customControl)
ExpandedBlockStart.gifContractedBlock.gif
{
    ActionsPaneControl customControl 
= new ActionsPaneControl(this);
ExpandedSubBlockStart.gifContractedSubBlock.gif  ActionsPane.Invoke(ActionsPane.Controls.Add,
new object[] new{customControl });//将Add方法委托给主线程调用
    frmPB.Close();//添加完后关闭并注销提示性窗体
    frmPB.Dispose(); 
}

这些代码经过本地测试,可以正常运行。

注意,虽然这个方法在我这里可以运行,但是根据 我这几天在网上查找的结果显示,导致这种错误的原因很多,应该根据你的实际情况来判断

现在懒得不行,写点字就累得不行

祝你好运!!

 

 

转载于:https://www.cnblogs.com/jjhe369/archive/2009/05/12/1455153.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值