注:本文原作者 Misha Shneerson 是 VSTO 团队的工程师。原文可以在下列地址找到:http://blogs.msdn.com/mshneer/archive/2007/09/05/deploying-your-vsto-add-in-to-all-users-part-i.aspx

  VSTO 插件(也叫“托管代码 Office 插件”)在部署方面有一个严重的不足,简单来说,微软只告诉了我们如何把这些插件部署到单个用户环境;而“如何一次性部署到一台机器的所有用户环境中”成为了我们的阿喀琉斯之踵。本文将给告诉你如何解决这个问题。

  首先让我们了解一些背景知识。

  Office 2007 已经内置了对托管代码插件的支持,通过一个叫“Manifest”的注册表值,Office 应用程序可以区分传统的 COM 插件和托管代码插件。这个键值可以在下列位置找到:HKCU\Software\Microsoft\Office\<App> \AddIns\<AddInName>。

  传统的 COM 插件可以通过在 HKLM\Software\Microsoft\Office\<App>\AddIns 注册自己的信息从而实现让本机所有的用户都可以使用。但是托管代码插件只能注册在 HKCU 里面,注册在 HKLM 里面的托管代码插件会被忽略。

  要创建一个安装包,做到能够往启动安装程序的那个用户的注册表里面写入 插件信息并不困难。但是,要把同样的信息复制到本机所有用户的注册表键里面,就需要比较高级的 Win32 API 使用技巧了。如果还要再稍微深入一步,我们可以让安装程序把插件注册信息写入“模板”(存在于 C:\Documents and Settings\Default User\ntuser.dat),这样可以保证将来使用本机的新用户直接就有相应的注册表信息。关于这种技巧,请参见 Raymond Chen 的文章

  已经在抓脑袋了?其实有一种相对来说容易得多的解决方案。诀窍就在于使用 Office 的一个内部机制,在用户启动 Office 应用程序的时候,把 HKLM 里面注册的信息复制到当前用户的 HKCU 里面去。

  针对 Office 2007,这个神奇的键值就在这里:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\User Settings。如果你的电脑已经安装了 Office 2007,你可以打开注册表编辑器察看一下那里(如果是 x64 的操作系统,则应该在 Wow6432Node 的相应位置里面)。你会发现里面有不少看似随机的键,这些随机的键里面,又有“Create”以及“Delete”键;再进入一层看,就会发现里面似乎包 含着某些完整路径的注册表信息!

  我们所见到的就是 Office 2007 的一种 HKLM 到 HKCU 的信息复制机制,而这种机制可以在注册表中进行完全的控制。让我们来进一步研究这种机制到底是怎么工作的。我们可以先做一个小练习——把下面的内容复制到 记事本程序,存为“testpropagation_create.reg”文件。然后运行这个文件,把其中的信息导入 HKLM。

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\User Settings\TestPropagation]
"Count"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\User Settings\TestPropagation\Create\Software\Microsoft\Office\TestKey]
"TestValue"="Test"

  然后启动 Excel 2007,再检查一下注册表,你会发现你的 HKCU 中,有两个新的键值被创建出来了:

  • HKCU\Software\Microsoft\Office\TestKey 有了一个值:TestValue
  • HKCU\Software\Microsoft\Office\12.0\User Settings\TestPropagation 有一个 Count 值,并且等于 1

  下一步,我们看看如何用同样的机制来删除键值。把下面的内容复制并保存到“testpropagation_delete.reg”文件,并且运行:

Windows Registry Editor Version 5.00
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\User Settings\TestPropagation\Create]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\User Settings\TestPropagation]
"Count"=dword:00000002
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\User Settings\TestPropagation\Delete\Software\Microsoft\Office\TestKey]

  高亮显示的文字标明了和之前一个文件不同的地方。我们先移除之前创建的 TestPropagation\Create 键,注意前面的“-”符号,它表示删除键值。为了让指令正确执行,我们需要保证 HKLM 里面的 Count 值和 HKCU 里面的 Count 值不同,所以把 Count 的值设置成了 2。最后,Software\Microsoft\Office\TestKey 被放在了 TestPropagation\Delete 里面,这样 Office 就知道应该是删除那个键值,而不是创建。

  执行了 testpropagation_delete.reg 之后,你会发现:

  • HKCU\Software\Microsoft\Office\TestKey 键已经被删除
  • HKCU\Software\Microsoft\Office\12.0\User Settings\TestPropagation 键的 Count 值被设置成了 2

  好了,现在我们已经清楚了 Office 的注册表键值复制机制是怎么工作的。至于怎么利用这种机制来改进我们的插件安装程序,应该也能猜个八九不离十了吧?在本文的下篇中,我们将一起来看如何为 一个 VSTO 2005 SE 的插件安装程序做一个自定义动作,结合上述机制,达到“部署到本机所有用户”的最终目的。