前面几篇文章讲解了Excel开发的几个比较主要的也是比较重要的方面,比如菜单系统,Excel对象模型,自定义函数,RTD函数,异步自定义函数,用户自定义任务面板等,在实际开发中我们还会遇到各种“千奇百怪”的问题,以及开发中的一些注意事项和技巧等,后面有空我会写文介绍。当我们的Excel外接应用程序开发好了之后,需要给用户使用,这就涉及到了应用程序的安装与部署,本文就简要介绍下Excel项目的安装和部署。 和一般的.NET 中的Windows Form程序不同,Excel开发通常是一种插件式的开发机制,它需要借宿在Excel上,并通过调用Excel的API来实现特定的业务逻辑。宿主Excel在运行的时候,会根据当前用户以及Excel版本信息,读取注册表特定位置,以查找在本机当前用户下面注册的插件信息,然后逐个加载。这里面就涉及到了和安装部署相关的一些需要考虑的问题了。 一 插件安装部署时需要考虑的问题Excel在安装部署的时候,需要考虑一些问题:
在部署插件的时候,以上问题在安装部署的时候是需要进行考虑,并通过代码的方式获取的。还有一些条件,比如用户有可能是安装的绿色版或者不完全版的Excel,这些奇奇怪怪的问题我们都需要考虑。 但是如果考虑到了以上条件,插件的安装和部署应该可以达到90%以上。 要了解Excel插件的安装部署我们需要清楚Excel是如何加载插件的,下面介绍下Excel插件的加载和运行机制。 二 Excel插件的加载及运行机制这里以VSTO Add-in为例,Shared Add-in原理和机制类似。 当我们使用Office开发工具来开发Add-in的时候,我们实际上是创建了一个用托管代码编写的能够被Office加载的程序集(assembly)。程序集加载之后,Add-in就能够响应Office应用程序发起的事件了。Add-in也可以调用Office开放的对象模型来扩展其功能,当然也可以使用.NET 类库中提供的各种功能。 程序集和Office的Com组件进行交互是通过Office提供的称之为Primary Interop Assembly (PIA)来实现的。 如果有多个VSTO创建的Add-in部署到了目标机器,在Office启动的时候,每一个Add-in会被加载到各自不同的AppDomain中,这样极大地提高了插件的稳定性,意味着如果有一个Add-in工作不正常,不会影响其他Add-in的功能,其次,当Office应用程序关闭的时候,所有的Add-in的程序集都可以从内存中清除。 虽然Add-in的程序集是开发中我们最要关注的东西,但是Office在发现和加载我们编写的Add-in的时候,其他几个组件和部分也发挥着重要作用。这对熟悉Add-in的安装和部署有着很重要的作用。 2.1 注册表项Excel 通过一系列的注册表项来加载插件。在部署的时候,我们也需要将我们插件的相关信息写入到目标机器的注册表中。通常在Vista及以上版本的Windows中对注册表的操作需要获得管理员权限。 a) 在部署的时候,我们需要确定是部署到CurrentUser还是LocalMachine节点下。 一般的软件在安装的时候都会提示该软件是仅适用我,还是所有人。如果是仅适用于我的话,就会将注册表信息保存在CurrentUser下,这样只有该用户登录才能看到该软件;如果是选择所有人的话,就会写到LocalMachine节点下。 使用Visual Studio创建的Add-in都可以部署到Current user下,但是并不是所有的都可以不会素到Local machine下,这可能和Offfice版本以及Add-in的部署方式有关。 还有一点需要注意的是,如果应用程序部署到了Local machine下面,那么在Excel插件中不会显示在Add-in外接程序列表中。 所以,一般的,我们会将应用程序部署到Current User下。 b) Office的版本信息 Office 2010和Office 2013可以加载HKEY_LOCAL_MACHINE 和HKEY_CURRENT_USER下面的Add-in,要加载HKEY_LOCAL_MACHINE 下面的Add-in需要安装976477补丁。 c) 部署类型 如果使用ClickOne部署Add-in,add-in只能在Current user下面部署,这是因为ClickOne仅支持在HKEY_CURRENT_USER下面读写注册表信息。如果要使机器上的所有用户都能够使用Add-in,那么需要使用Windows Installer来部署Add-in。
2.2 注册表值这里以部署到HKEY_CURRENT_USER为例,LOCAL_MACHINE下面类似。 一般滴,Excel各产品会在Root\Software\Microsoft\Office\application name\Addins\add-in 下面寻找对应的注册表项。这也是最重要的一个注册表项值,上图列出的是一个我们在之前文章中创建的那个简单的名为YYAddin的VSTO程序。对于Shared Add-in开发的插件,该注册表信息类似,不过也有些区别后面会说明。 这个节点下面的注册表键值对需要说明一下。
基本上对于VSTO 应用程序,只需要将以上部分的注册表项写入到目标机器上即可完成安装部署。 2.3 VSTO Runtime使用VSTO创建的Add-in程序,终端用户也需要安装VSTO的运行时环境。该运行时环境包含一些非托管组件以及一些托管的程序集。非托管的程序集被加载到Add-in的程序集中。托管程序集提供的对象模型能够使得Add-in代码可以调用Excel开放的API扩展其功能。 2.4 加载逻辑当用户打开Office 软件的时候,Office使用部署的程序及清单来定位和加载Add-in的程序集,如下图所示: 以VSTO创建的Add-in为例, 步骤如下:
三 实施对于Excel插件的部署,这里分两块介绍,一个是VSTO项目的部署,一个是Com Shared Add-in类型项目的部署。 3.1 VSTO创建的插件的项目部署关于VSTO的部署,对于Document Level的项目文件,直接可以创建一个部署项目或者使用ClickOnce部署。非常简单,博客园中,Mr.Brooks同学写过一篇有关VSTO部署的文章 VSTO 学习笔记(十三)谈谈VSTO项目的部署,这里不再赘述了。 从上图的注册表信息的Manifest可以看出,VSTO项目的程序集清单其实是一个.vsto文件,它是VSTO项目部署时的安装文件,用文本编辑器打开,可以看到他是一个xml文件,包含了VSTO项目的具体信息,如.NET运行时版本,依赖的程序集,数字签名等信息。 该文件默认会使用Visual Studio Tools For Office Execution Engine打开,该组件包含在该组件包含于Visual Studio Tools For Office 运行时,因此客户端若要运行VSTO程序,还需要安装Visual Studio Tools For Office 运行时环境。Visual Studio 2010 Tools for Office Runtime 可以在这里下载。实际上,如果客户机器上安装了VSTO运行时环境,只需要把编译好的debug目录拷贝到目标机器,部署的时候,只需双击.vsto这个文件就可以完成安装和部署。 如果将插件作为单独的产品发布,以上安装部署没有任何问题。但是很多时候,插件是作为产品的一部分发布的。所以我们需要一种更灵活的方式来对项目进行部署。插件的部署在本质上就是对注册表项的读写,了解这一点就很容易了。下面就简要介绍一下如何通过手动写入注册表信息的方式部署VSTO项目。 如前所述,Excel加载插件是通过查找特定注册表位置来加载的,所以我们只需要在这些位置写入注册表信息即可。以部署我们的YYAddin为例,首先找到开发机上Visual Studio为我们创建好的注册表项,然后右键导出。保存为注册表类型后缀为.reg的文件。 用记事本打开该reg文件。这个文件就是该Add-in在注册表项中的所有内容了。我们在实际部署的时候,可以创建一个exe文件,获取用户的系统位数,和安装目录,修改该文件中的跟路径,以及Manifest路径,然后再动态生成一份该文件,导入到目标机器即可以完成安装和部署。 3.2 Com SharedAddin创建的插件的项目部署和VSTO开发的插件不同,使用Shared Add-in开发的插件实际上是一个Com组件,除了在Root\Software\Microsoft\Office\application name\Addins\add-in 下面有相应的信息之外,在ClassRoot中还有一些信息,这里以我们在前面文章中创建的名为YYSharedAddin的项目为例。先看看在Excel节点下的注册表信息: 部署的方法和VSTO相同,只需要将该注册表项导出,然后写入到目标机器即可。但是这只是第一步。细心的读者会发现和VSTO项目相比,缺少了Manifest这个键值对,Excel仅仅只要有一个名为YYSharedAddin.Connect 的插件需要加载,但是这个插件的程序集在哪里呢?我们接着在注册表中搜索YYSharedAddin.Connect。可以看到如下结果。 其中ProgId的值为YYSharedAddin.Connect ,这个ProgId以及 该节点的Guid即为我们在创建Shared Add-in的时候人为指定的。如下图:
Visual Studio在编译和调试的时候实际上是帮我们调用了一下指令: regasm " D:/YYUDF/YYAddIn/YYSharedAddin/bin/Debug/YYSharedAddin.dll " /codebase /s 该语句即可将相关的注册表信息写入到注册表项中去了。这样连同之前导入的注册表,使用Shared Add-in创建的加载项的部署就完成了。 3.3 其它相关模块的部署除了我们的主程序之外,通常我们使用Com组件方式写的UDF函数,RTD函数,以及CTP等,也都需要写入到注册表中,最简单的方法和上面一样,直接使用微软提供的Regasm工具,读取程序集中的元数据,并将所需的项添加到注册表中。在部署的时候我们只需要将regasm这个工具打包一起发布,然后安装的时候调用该命令即可。 还有一个问题,就是如果您是使用的.NET 2.0开发的Shared Add-in程序,目标机器上安装的是Office 2003,那么需要注意的是,Excel 2003 和Word 2003 可能在加载使用.NET 2.0创建的插件的时候可能会出现问题,因此,需要安装名为office2003-KB907417-FullFile-ENU.exe 和extensibilityMSM.msi的Office补丁。所以在部署的时候,需要判断用户的Excel版本,以及该版本是否已经安装了该补丁,如果没有,需要首先静默安装此补丁。 四 结语Excel插件的安装和部署是比较重要的一个环节,由于和传统的Windows Form应用程序不同,作为一种寄宿的插件,它需要往注册表中写入东西。本文首先介绍了Excel加载插件的步骤,Excel插件的注册表组成部分。随后介绍了使用VSTO和Shared Add-in创建插件的部署方式及注意事项。原理都是类似,就是往注册表里面写入注册信息。对于Shared Add-in创建的插件,除了写入必要的注册表信息之外,还需要使用regasm来将dll注册为COM可见,其实也就是通过工具来帮助我们往注册表里写入信息。使用类库方式开发的UDF函数,RTD函数以及CTP都需要使用regasm的方式注册,才能在Excel中进行调用。最后介绍了在Office 2003中要使用插件必须要安装的两个补丁,完成了这些步骤,您开发的插件基本上就可以部署到绝大部分的目标机器上了。 希望本文对您了解Excel插件的加载机制和安装部署有所帮助。 |
|