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 theManage DropDownList->Click Button Go
    • o   Office 2003:Right Click the Menu->Click Customize… Button->In Commands Tab->ToolsCategorie->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 theManage DropDownList->Click Button Go
    • o   Office 2003:Menu Help->About Microsoft Office Excel->Disabled Items

最新文章

  1. PostgreSQL的 initdb 源代码分析之三
  2. cocos2dx arpg单机手游
  3. REDIS主从配置及切换
  4. Boost下载安装编译配置使用指南(含Windows和Linux
  5. 认识mongoDB数据库
  6. X86在逻辑地址、线性地址、理解虚拟地址和物理地址
  7. 智能的API、云服务和SOA测试解决方案——Parasoft SOAtest
  8. 调用ZoomEye API获取信息
  9. [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
  10. Linuxc - 标准输入流、标准输出流、标准错误流
  11. discuz全新安装升级,导入旧数据过程,顺便gbk转utf8
  12. JavaScript之深入理解【函数】
  13. PreparedStatement传进null值报错
  14. sql server对已创建的表增加属性(自动增序)
  15. Linux之网络编程:时间服务器
  16. Xshell Plus
  17. 洗礼灵魂,修炼python(49)--巩固篇—包
  18. Java上传文件FTP服务器代码
  19. Bug:java.lang.StackOverflowError: stack size 8MB
  20. [k8s] kubelet单组件启动静态pod

热门文章

  1. [问题解决]Fresco设置占位图不显示的问题
  2. ECharts概念学习系列之ECharts是什么?
  3. C 标准库 - string.h之memmove使用
  4. python实例:快速找出多个字典中的公共键
  5. CADisplayLink+弹簧动画实现果冻效果
  6. 【TCP协议】MTU和MSS详解
  7. 手把手教你使用 VuePress 搭建个人博客
  8. json跨域问题
  9. 关于键盘KeyDown事件
  10. 多线程-lock锁