Winform使用DSO Framer控件嵌入office 异常总结及解决方法
1.DSO Framer无法激活不可见或已禁用的控件
因为业务需求,执行了一次清空面板main_panel所有控件,之后未向窗体面板main_panel中添加过OfficeFramerControl,直接调用了OfficeFramerControl.Open();
OfficeFramerControl.Open("D:\\文件路径");
抛出异常
//System.ArgumentException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>无法激活不可见或已禁用的控件</Message><StackTrace> 在 System.Windows.Forms.ContainerControl.SetActiveControlInternal(Control value)
//在 DSOFramer._FramerControl.Open(Object Document, Object ReadOnly, Object ProgId, Object WebUsername, Object WebPassword)</StackTrace><ExceptionString>System.ArgumentException: 无法激活不可见或已禁用的控件
//“System.Reflection.TargetInvocationException”类型的未经处理的异常在 mscorlib.dll 中发生调用的目标发生了异常。
将控件添加到面板后再调用打开方法,原代码改为:
main_panel.Controls.Add(OfficeFramerControl);
OfficeFramerControl.Open("D:\\文件路径");
2.COMException (0x80010001): 被呼叫方拒绝接收呼叫。
OfficeFramerControl.Open(“D:\文件路径”);
刚开始打开office时是正常的,试了几次之后突然开始抛出被呼叫方拒绝接收呼叫。
异常信息:
在 DSOFramer._FramerControl.Open(Object Document, Object ReadOnly, Object ProgId, Object WebUsername, Object WebPassword)System.Runtime.InteropServices.COMException (0x80010001): 被呼叫方拒绝接收呼叫。
查了很多资料,参考文章:
https://blog.csdn.net/jiongxian1/article/details/79552857
https://msdn.microsoft.com/zh-cn/library/ms228772(v=vs.120).aspx
刚开始看的云里雾里的,不太理解。这里记录一下个人理解的部分。
使用DSO Framer Control时在工具箱右键->选择项,打开选择工具箱项,勾选其中的中DSO Framer Control Object,所以一开始以为是该组件的注册出现了问题,然后重新进行了DSO Framer控件的ocx文件注册。
注册方法可以参考这篇博文,不再赘述: https://blog.csdn.net/sinat_35187039/article/details/82999644
但其实重新注册后也没有解决,仍然抛这个异常。看了msdn的文章后,大概明白了原因是因为VS以编程方式从外部(进程外)多线程应用程序调入 Visual Studio 自动化就有可能抛这个异常。
具体是因为外部多线程应用程序(如office应用程序)与 Visual Studio 之间存在线程争用问题。
通过在 Visual Studio 自动化应用程序中实现 IOleMessageFilter 错误处理程序可以消除这些错误。(不要将 IOleMessageFilter 与 System.Windows.Forms.IMessageFilter 混淆。)
按照msdn中给的修复步骤,理解了一下msdn给出的示例代码。
1.将以下类添加到应用程序中。
using System;
using System.Collections.Generic;
using System.Text;
using EnvDTE;
using EnvDTE80;
using System.Runtime.InteropServices;
using System.Windows.Forms;
这个时候EnvDTE,EnvDTE80提示error,不要紧,继续往下就能解决了。
2.添加指向“Microsoft 开发环境 8.0”的 COM 引用。此操作将对 EnvDTE 和 EnvDTE80 的引用添加到解决方案中。
在项目名下点击引用右键->添加引用,
打开引用管理器,选择COM,搜索找到Microsoft Development Environment 8.0,勾选,确定。
现在引用中多了EnvDTE,EnvDTE80。EnvDTE,EnvDTE80程序不再报error。
3.添加对 System.Windows.Forms 的引用。
在代码头部中加入
using System.Windows.Forms;
4.在代码中,创建 EnvDTE80 的实例
msdn给出的示例代码是这样的,ProgID以"VisualStudio.DTE.10.0"举例了。
EnvDTE80.DTE2 dte;object obj = null;System.Type t = null;// Get the ProgID for DTE 8.0.t = System.Type.GetTypeFromProgID("VisualStudio.DTE.10.0",true);// Create a new instance of the IDE.obj = System.Activator.CreateInstance(t, true);// Cast the instance to DTE2 and assign to variable dte.dte = (EnvDTE80.DTE2)obj;
但因为我这里用的是dso framer ,没修改直接执行的时候抛出了
引发的异常:“System.Runtime.InteropServices.COMException”(位于 mscorlib.dll 中)
“System.Runtime.InteropServices.COMException”类型的未经处理的异常在 mscorlib.dll 中发生
无效的类字符串 (异常来自 HRESULT:0x800401F3 (CO_E_CLASSSTRING))
理解后明白msdn提供的ProgID是"VisualStudio.DTE.10.0",但我根本没有注册这个控件,所以要改成我已经注册过的dso framer 控件的ProId。然后这里的ProId我又不理解了,解决方法,分类以下,放在这篇博文里:
ProgID 为 DSOFramer.FramerControl,修改后代码。
EnvDTE80.DTE2 dte;object obj = null;System.Type t = null;// Get the ProgID for DTE 8.0.t = System.Type.GetTypeFromProgID("DSOFramer.FramerControl", true);// Create a new instance of the IDE.obj = System.Activator.CreateInstance(t, true);// Cast the instance to DTE2 and assign to variable dte.dte = (EnvDTE80.DTE2)obj;
之后运行还是抛异常。
System.InvalidCastException:“无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类型“EnvDTE80.DTE2”。此操作失败的原因是对 IID 为“{2EE1E9FA-0AFE-4348-A89F-ED9CB45C99CF}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 不支持此接口 (异常来自 HRESULT:0x80004002 (E_NOINTERFACE))。”
到这里我已经没有力气研究下去了,看到上面那篇的博主说msdn举得例子不用全部使用,只要在程序前后进行MessageFilter.Register();和MessageFilter.Revoke();就可以!!!开心的像个200斤的胖子,集中精力理解MessageFilter。
5.调用 Message.Register 处理线程错误。
直接使用了msdn的源代码。
public class MessageFilter : IOleMessageFilter{//// Class containing the IOleMessageFilter// thread error-handling functions.// Start the filter.public static void Register(){IOleMessageFilter newFilter = new MessageFilter();IOleMessageFilter oldFilter = null;CoRegisterMessageFilter(newFilter, out oldFilter);}// Done with the filter, close it.public static void Revoke(){IOleMessageFilter oldFilter = null;CoRegisterMessageFilter(null, out oldFilter);}//// IOleMessageFilter functions.// Handle incoming thread requests.int IOleMessageFilter.HandleInComingCall(int dwCallType,System.IntPtr hTaskCaller, int dwTickCount, System.IntPtrlpInterfaceInfo){//Return the flag SERVERCALL_ISHANDLED.return 0;}// Thread call was rejected, so try again.int IOleMessageFilter.RetryRejectedCall(System.IntPtrhTaskCallee, int dwTickCount, int dwRejectType){if (dwRejectType == 2)// flag = SERVERCALL_RETRYLATER.{// Retry the thread call immediately if return >=0 & // <100.return 99;}// Too busy; cancel call.return -1;}int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,int dwTickCount, int dwPendingType){//Return the flag PENDINGMSG_WAITDEFPROCESS.return 2;}// Implement the IOleMessageFilter interface.[DllImport("Ole32.dll")]private static extern intCoRegisterMessageFilter(IOleMessageFilter newFilter, outIOleMessageFilter oldFilter);}[ComImport(), Guid("00000016-0000-0000-C000-000000000046"),InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]interface IOleMessageFilter{[PreserveSig]int HandleInComingCall(int dwCallType,IntPtr hTaskCaller,int dwTickCount,IntPtr lpInterfaceInfo);[PreserveSig]int RetryRejectedCall(IntPtr hTaskCallee,int dwTickCount,int dwRejectType);[PreserveSig]int MessagePending(IntPtr hTaskCallee,int dwTickCount,int dwPendingType);}
6.按常规方式调用自动化代码。
在打开文件open方法前后地方加入注册和移除方法。
MessageFilter.Register();axFramerControl1.Open("D:\\personal\\IT\\SITRI Trainging APP\\SITRI Training APP 系统界面设计.xlsx");MessageFilter.Revoke();
最后再次运行,虽然不抛COMException (0x80010001): 被呼叫方拒绝接收呼叫的异常了,但是程序卡在被拒绝后无限重试中,,,还是没有正确打开文件!
绝望惹~~先记录到这里,等研究明白了再来补充,有明白的大佬还望多多指点迷津!!
Winform使用DSO Framer控件嵌入office 异常总结及解决方法相关推荐
- Chart控件X轴显示不全的解决方法
Chart控件X轴显示不全的解决方法 参考文章: (1)Chart控件X轴显示不全的解决方法 (2)https://www.cnblogs.com/topmount/p/8430689.html 备忘 ...
- WinForm界面开发第三方控件——支持Office 2019 Light主题
Telerik UI for WinForms最新版下载 Telerik UI for WinForms拥有适用Windows Forms的110多个令人惊叹的UI控件.所有的UI for WinFo ...
- DevExpress Winform 所有可打印控件(gridcontrol等)通用导出excel方法
涛神联合Dxper.Net开发者论坛管理在腾讯课堂开启DevExpress培训课程 详情可以加群QQ群:294560883 关于DevExpress Winform 的所有可打印控件的导出excel ...
- 英文操作系统下WebBrowser控件无法显示本地页面的解决方法
解决方法有两种: 1.将程序安装在英文路径即页面全路径中不含中文. 2.修改系统区域设置,改为中国,具体如下: Control Panel->Region and Language Format ...
- 分享DotNetBar控件制作office 2007风格界面的视频教程(winform office 2007 风格)
http://www.51aspx.com/Code/DotNetBarOffice之前利用dotnetbar控件做了个winform小程序:分享一个DotNetBar做的三层架构的winForm程序 ...
- WinForm中使用Excel控件
最近项目中要在WinForm中使用Excel控件,经过几天的研究,现在总结一下成果. 在WinForm中使用Excel控件主要有三种方法:WebBrowser.DSOFramer.OWC.下面分别 ...
- [转] WinForm实现移除控件某个事件的方法
原文 WinForm实现移除控件某个事件的方法 本文实例讲述了WinForm实现移除控件某个事件的方法,供大家参考借鉴一下.具体功能代码如下: 主要功能部分代码如下: 1 2 3 4 5 6 7 8 ...
- c#在WinForm中重写ProgressBar控件(带%的显示)
c#在WinForm中重写ProgressBar控件(带%的显示) 2009-05-14 13:13 #region 定义textProgressBar控件的类 namespace csPublish ...
- 如何将第三方控件嵌入ToolStrip控件,并提供Design-Time支持
最近研究了一下如何将第三方控件嵌入到ToolStrip控件中,并能提供Design-Time下的支持. 下面将详细讲解如何把系统的MonthCalendar控件嵌入到ToolStrip控件中. 以下的 ...
最新文章
- 当OpenCV遇到VS2019时,以前的配置方式翻车了….
- SharePoint 如何找到List的Template ID
- Linux CentOS添加163yum源
- PHP判断是否为手机客户端
- unity 编辑器扩展 扩展摄像机的属性查看器
- 真香警告!2021Android高级面试题,挥泪整理面经
- 神龙架构没那么难理解—图解世界领先的阿里云神龙架构(二)神龙出世
- Spring与Struts框架整合
- golang中defer语句使用小结
- 用友CDM系统,将货位间商品移库单(一步)修改为内调出入库单(一步)方法使用...
- Try Microsoft AutoCollage 2008
- 使用 Google Guava 美化你的 Java 代码
- OpenCasCade默认的小坐标系的构建
- 激光雕刻机DIY之二:GRBL的下载与参数配置
- 中职计算机专业英语说课稿,中职英语基础模块说课
- mybatis 一对一 ,一对多,多对多的实现
- linux下通过wifi连接网络
- 大一上军事理论网课章测试及见面课答案
- 方正计算机驱动程序,方正Founder A321驱动
- 正高职称 程序员_正高级工程师评审条件最新版
热门文章
- 用zrender制作一个基础的绘图板,绘图板可用于组态界面的基础性开发
- Java虚拟机--Java虚拟机栈
- python抠图精确到发丝_ps抠图有一些发丝怎么扣
- 《人月神话》8 胸有成竹(Chaptor 8.Calling the Shot -The Mythical Man-Month)
- AD18版本中测距之后显示信息不能清除
- div的display和visible的区别
- Pytorch函数之topk()方法
- Swift中键盘的弹出隐藏,页面抬高,Return键等的配置
- 人体的神经系统图 分布,神经系统分布图解析图
- 使用Weka进行数据可视化