详解Office 外接程序 COM Add In的LoadBehavior及其妙用
Office的所有COM Add In,包括用Shared Add In模板和VSTO Add In模板创建的,都会在注表里面存储一些信息。对于当前用户安装的Add In,以Excel为例,对应的注册表键值存储于:My Computer"HKCU"Software"Microsoft"Office"Addins"AddInName;机器级别的Add In存储于:My Computer"HKLM"Software"Microsoft"Office"Addins"AddInName。普通的Shared Add In, 键下面有3个值,Description,FriendlyName,LoadBehavior。VSTO Add In多出两个键值:CommandLineSafe和Manifest。Manifest是用来指向自定义代码所处的dll位置的,CommandLineSafe用来指示Add In是不是命令行安全的,会不会显示在COM Add In Dialog里面。Description和FriendlyName就是Add In的描述和显示的名字,没啥好说的。
而LoadBehavior是这篇文章的主角。LoadBehavior指示了该Add In的装载行为,它可以由以下几个值组合而成: (前两个中的一个+后三个中的一个)
0 = Disconnect |
不装载 |
1 = Connected |
装载 |
2 = Bootload |
启动程序时装载 |
8 = DemandLoad |
需要时装载 |
16 = ConnectFirstTime |
第一次启动时装载 |
也就是说,当LoadBehavior为0,2,8,16的时候,Add In不装载;当其为1+2=3的时候,装载并且每次Office程序启动时都装载;当其为9的时候,装载,但只当用户需要时装载;17的时候,装载,只有第一次启动的时候装载。如果我们不去改动,一般而言,正常工作的Add In其LoadBehavior是3,但如果当Add In启动的时候发生异常,这个Add In会被软禁用(Soft Disabled),LoadBehavior的值会被改为0+2=2,Add In将不被装载。注意,虽然这里的值是2,表示启动时装载,但事实上,其是由0+2所得,大的前提决定了不装载。
那我说的LoadBehavior的妙用在何处呢?这源于最近碰到的一个问题,有人问我,能不能用代码来获取Office中被硬禁用(Hard Disable)的COM Add In,或者至少知道,有没有被硬禁用的Add In?这个问题有点棘手,因为Office对象模型中,根本找不到任何信息。Google甚至都找不到,有人有类似的要求。
在给出解决方案前,有必要讲述一下,上面提到的硬禁用和软禁用的区别。首先,硬禁用和软禁用的表象就不一样,被软禁用的Add In会出现在COM Add-Ins对话框中,只不过前面的Checkbox不会被勾上。被硬禁用的Add In虽然也会出现在COM Add-Ins对话框中,但它们会被单独再列到另外一个叫Disabled Items的对话框里面。下面是COM Add-Ins对话框和Disabled Items对话框的截图。由下面的图可以看出来ExcelAddIn和ExcelAddIn1是被用户手动禁用,或者被软禁用的;ExcelAddIn2则是被硬禁用的。
COM Add-Ins 软禁用 对话框截图
Disabled Items 硬禁用 对话框截图
硬禁后第一次开启时的提示
那是什么导致Add In被软禁用和硬禁用的呢?为了模拟出问题,并解决,我也必须让自己的机器上出现一个被软禁用,一个被硬禁用的Add In。
软禁用:当Add In在构造函数或者Startup event handle函数里面抛出一个没有处理的异常的时候,系统将该Add In软禁用,将其LoadBehavior值改为2。要重现一个软禁用很简单,在Startup event handle里面抛出一个异常就可以了,代码如下:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
throw new Exception("Make the Add in disabled");
}
硬禁用:发生在,Add In装载时由于严重的错误导致应用程序关闭,或者在构造函数或Startup event handle函数执行时,强行关掉Visual Studio Debugger时。这将导致再一次启动应用程序的时候,Office向用户询问是否硬禁用当前Add In。方法同样很简单,用一个MessageBox停住Startup event handle函数的执行过程,然后强行关掉Visual Studio,下次程序(本例Excel)启动时,选择禁用Add In。
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
MessageBox.Show("Stop here");
}
接下来,看看上面问题的解决方案。在Office对象模型中,Application对象有个COMAddIns属性,它是一个集合,包括了当前应用程序中所有注册过的COM Add In,无论这个Add In是否激活。我们可以在这个集合中循环,得到每个COMAddIn的句柄,而COMAddIn又暴露了一些有用的属性,比如Connect属性。当Connect返回true时,说明这个Add In是激活的,如果返回false,说明这个Add In未激活,有可能是被用户手动禁用了,还有可能是被软禁用或硬禁用了。但是COMAddIn的属性只告诉我们这么多,通过Office对象模型,我们无法分辨,应用程序中是否存在被硬禁用的Add In,如果有,哪些是被硬禁用的Add In。通过查看硬禁用的Add In在注册表中LoadBehavior的值,惊奇地发现,硬禁用的Add In,其LoadBehavior值竟然为3!这样我们就可以结合COMAddIns集合和注册表里LoadBehavior的信息来判断哪些COM Add In是被硬禁用的,哪些是由于软禁用或者其它原因未被装载的。实现的代码如下:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
RegistryKey key = null;
foreach(Office.COMAddIn cAddin in this.Application.COMAddIns)
{
if (!cAddin.Connect)
{
try
{
key = Registry.LocalMachine;
key = key.OpenSubKey("Software").OpenSubKey("Microsoft")
.OpenSubKey("Office").OpenSubKey("Excel").OpenSubKey("Addins")
.OpenSubKey(cAddin.ProgId);
if (Convert.ToInt32(key.GetValue("LoadBehavior")) == 3)
{
MessageBox.Show(cAddin.ProgId + " is disabled!");
}
else
{
MessageBox.Show(cAddin.ProgId + " is not loaded!");
}
}
catch(Exception ex)
{
key = Registry.CurrentUser;
key = key.OpenSubKey("Software").OpenSubKey("Microsoft")
.OpenSubKey("Office").OpenSubKey("Excel").OpenSubKey("Addins")
.OpenSubKey(cAddin.ProgId);
if (Convert.ToInt32(key.GetValue("LoadBehavior")) == 3)
{
MessageBox.Show(cAddin.ProgId + " is disabled!");
}
else
{
MessageBox.Show(cAddin.ProgId + " is not loaded!");
}
}
}
}
}
PS:如何显示COM Add-ins和Disabled Items对话框?(没有中文的Office,所以菜单和按钮都按英文版中的写法,对照着应该很好找到)
· COM Add-ins对话框:
o Office 2007:Office Button->Excel Options->Add-Ins Tab->Choose Item COM Add-ins in the Manage DropDownList->Click Button Go
o Office 2003:Right Click the Menu->Click Customize… Button->In Commands Tab->Tools Categorie->Drag COM Add-Ins Command to one of the tool bar->Click the new added COM Add-ins Button
· Disabled Items对话框:
o Office 2007:Office Button->Excel Options->Add-Ins Tab->Choose Item Disabled Items in the Manage DropDownList->Click Button Go
o Office 2003:Menu Help->About Microsoft Office Excel->Disabled Items
详解Office 外接程序 COM Add In的LoadBehavior及其妙用的更多相关文章
- [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)
原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...
- 详解微信小程序开发(项目从零开始)
一.序 微信小程序,估计大家都不陌生,现在应用场景特别多.今天就系统的介绍一下小程序开发.注意,这里只从项目代码上做解析,不涉及小程序如何申请.打包.发布的东西.(这些跟着微信官方文档的流程走就好). ...
- 详解COM Add In的LoadBehavior及其妙用
Office的所有COM Add In,包括用Shared Add In模板和VSTO Add In模板创建的,都会在注册表里面存储一些信息. 对于当前用户安装的Add In,以Excel为例,对应 ...
- 详解Office Add-in 清单文件
作者:陈希章 发表于2017年12月8日 前言 我们都知道,一个Office Add-in,最主要是由两个部分组成的:清单文件(manifest)和真正要用来执行的网站. 清单文件其实是一个标准的XM ...
- 【转】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程
http://blog.csdn.net/xiaominghimi/article/details/6937097 //——2012-12-11日更新 获取"产品付费数量等于0这个问题& ...
- 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取”产品付费数量等于0的问题”】
转的别人的 看到很多童鞋问到,为什么每次都返回数量等于0?? 其实有童鞋已经找到原因了,原因是你在 ItunesConnect 里的 “Contracts, Tax, and Banking”没有完成 ...
- 详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程
Himi 原创, 欢迎转载,转载请在明显处注明! 谢谢. 原文地址:http://blog.csdn.net/xiaominghimi/article/details/6937097 //——201 ...
- Bullet核心类介绍(Bullet 2.82 HelloWorld程序及其详解,附程序代码)
实验平台:win7,VS2010 先上结果截图: 文章最后附有生成该图的程序. 1. 刚体模拟原理 Bullet作为一个物理引擎,其任务就是刚体模拟(还有可变形体模拟).刚体模拟,就是要计算预测物体的 ...
- [js高手之路] es6系列教程 - Set详解与抽奖程序应用实战
我们还是从一些现有的需求和问题出发,为什么会有set,他的存在是为了解决什么问题? 我们看一个这样的例子,为一个对象添加键值对 var obj = Object.create( null ); obj ...
随机推荐
- margin和padding的区别和用法
margin和padding的区别和用法 什么是margin.padding? marigin:就是外边距.padding:就是内边距.怎么就容易记住两者呢? 马蓉大家都知道吧,给王宝强带帽子的那位, ...
- jQuery CSS 操作函数(六)
CSS 属性 描述 css() 设置或返回匹配元素的样式属性. height() 设置或返回匹配元素的高度. offset() 返回第一个匹配元素相对于文档的位置. offsetParent() 返回 ...
- 使用git工具将项目上传到github
注册github账号 https://github.com/ 安装git工具: https://git-for-windows.github.io/ 上面的准备工作完成后,现在开始操作. 一.进入gi ...
- 搭建Vue.js开发环境(window10)
我在配置Vue.js环境的时候遇到了很多的问题,希望能把这些解决方法也介绍给大家,希望能帮到大家,共同学习. 如果要转发,请注明原作者和原产地,谢谢! 注释:下面任何命令都是在windows的命令行工 ...
- [Spark内核] 第36课:TaskScheduler内幕天机解密:Spark shell案例运行日志详解、TaskScheduler和SchedulerBackend、FIFO与FAIR、Task运行时本地性算法详解等
本課主題 通过 Spark-shell 窥探程序运行时的状况 TaskScheduler 与 SchedulerBackend 之间的关系 FIFO 与 FAIR 两种调度模式彻底解密 Task 数据 ...
- vmvare centos 7.0 root密码忘记后重置及总结
今天遇到了一个比较尴尬的事情,我centos 7.0的虚拟机密码忘了.....里面还有我配置好的环境呢.于是我就上网上搜索各种方法,最后经我验证下面这个方法比较靠谱: 使用光盘修复Centos: ht ...
- Fineui js getText
需要自己写js的时候.需要取值. var ddlgenderid='<%=ddlgender.clientID%>';function reader(value){f(ddlgenderi ...
- 【转载】MySQL之权限管理
一.MySQL权限简介 关于mysql的权限简单的理解就是mysql允许你做你全力以内的事情,不可以越界.比如只允许你执行select操作,那么你就不能执行update操作.只允许你从某台机器上连接m ...
- HtmlWebpackPlugin实现资源的自定义插入
目前碰到的问题 我们用html-webpack-plugin的inject属性去自动插入打包后的js, css到页面中,但是如果想给script标签添加一个crossorigin属性呢, 例如: &l ...
- MIPI协议-DSI
对于现代的智能手机来说,其内部要塞入太多各种不同接口的设备,给手机的设计 和元器件选择带来很大的难度.下图是一个智能手机的例子,我们可以看到其内部存储.显示.摄像.声音等内部接口都是各不相同的.即使以 ...