使用 Windows Installer 部署 VSTO 解决方案

总结

了解如何使用 Visual Studio 安装程序 项目部署 Microsoft Visual Studio Tools for 办公室 (VSTO) 外接程序或文档级解决方案。

沃特·范·沃格特,代码顾问

泰德·帕蒂森,泰德·帕蒂森集团

本文由 Microsoft 使用原始作者的权限进行更新。

适用于:Visual Studio Tools for 办公室、Microsoft 办公室、Microsoft Visual Studio。

可以使用 Windows Installer 包开发 VSTO 解决方案并部署解决方案。 此讨论包括部署简单办公室外接程序的步骤。

部署方法

ClickOnce 可以轻松地用于为加载项和解决方案创建设置。 但是,它无法安装需要管理权限的外接程序,例如计算机级外接程序。

可以使用 Windows Installer 安装需要管理权限的加载项,但它确实需要更多精力来创建安装程序。

有关如何使用 ClickOnce 部署 VSTO 解决方案的概述,请参阅使用 ClickOnce 部署办公室解决方案。

部署面向 VSTO 运行时的办公室解决方案

安装办公室解决方案时,ClickOnce 和 Windows Installer 包需要执行相同的基础任务。

  1. 在用户计算机上安装必备组件。
  2. 部署解决方案的特定组件。
  3. 对于加载项,请创建注册表项。
  4. 信任解决方案以允许其执行。

目标计算机上的必需先决条件组件

下面是必须安装在计算机上才能运行 VSTO 解决方案的软件列表:

  • Microsoft 办公室 2010 或更高版本。
  • Microsoft .NET Framework 4 或更高版本。
  • Microsoft Visual Studio 2010 Tools for Office Runtime。 运行时提供管理加载项和文档级解决方案的环境。 运行时版本随Microsoft 办公室一起提供,但你可能希望通过加载项重新分发特定版本。
  • 如果不使用嵌入式互操作类型,则Microsoft 办公室的主要互操作程序集。
  • 项目引用的任何实用工具程序集。

解决方案的特定组件

安装程序包必须将这些组件安装到用户的计算机上:

  • 如果创建文档级解决方案,则Microsoft 办公室文档。
  • 自定义程序集及其所需的任何程序集。
  • 其他组件,例如配置文件。
  • 应用程序清单(.manifest)。
  • 部署清单(.vsto)。

加载项的注册表项

Microsoft 办公室使用注册表项来查找和加载外接程序。应在部署过程中创建这些注册表项。 有关这些注册表项的详细信息,请参阅 VSTO 外接程序的注册表项。

显示自定义窗体区域的 Outlook 外接程序需要其他注册表项,这些注册表项允许标识窗体区域。 有关注册表项的详细信息,请参阅 Outlook 窗体区域的注册表项。

文档级解决方案不需要任何注册表项。 相反,文档内的属性用于查找自定义项。 有关这些属性的详细信息,请参阅 自定义文档属性概述

信任 VSTO 解决方案

若要运行自定义项,计算机必须信任解决方案。 可以通过使用证书对清单进行签名、创建与包含列表的信任关系,或通过将清单安装到计算机上的受信任位置来信任外接程序。

有关如何获取证书进行签名的详细信息,请参阅 ClickOnce 部署和验证码。 有关信任解决方案的详细信息,请参阅使用包含列表信任办公室解决方案。 可以在 Windows Installer 文件中添加包含列表条目和自定义操作。 有关启用包含列表的详细信息,请参阅 如何:配置包含列表安全性

如果未使用这两个选项,则会向用户显示信任提示,让他们决定是否信任解决方案。

有关与文档级解决方案相关的安全性的详细信息,请参阅 授予对文档的信任。

创建基本安装程序

安装程序和部署项目模板包含在可供下载的 Microsoft Visual Studio 安装程序 Projects 扩展中。

若要为办公室解决方案创建安装程序,必须完成以下任务:

  • 添加将部署的办公室解决方案的组件。
  • 对于应用程序级外接程序,请配置注册表项。
  • 配置必备组件,以便它们可以安装在最终用户计算机上。
  • 配置启动条件以验证所需的必备组件是否可用。 如果未安装所有必需的先决条件,可以使用启动条件来阻止安装。

第一步是创建安装项目。

创建 AddIn 安装程序项目

  1. 打开要部署的 办公室 AddIn 项目。 在本示例中,我们使用名为 ExcelAddIn 的 Excel 外接程序。
  2. 打开办公室项目后,在“文件”菜单上,展开“添加”,然后单击“新建项目添加新项目。
  1. “添加新项目 ”对话框中,选择 “安装项目 ”模板。
  2. 单击“下一步”。
  1. “名称”框中,键入办公室AddInSetup
  1. 单击“创建创建新的安装项目。

Visual Studio 将打开新安装项目的文件系统资源管理器。 文件系统资源管理器允许将文件添加到安装项目。

Screenshot of the File System Explorer for the setup project

图 1:安装项目的文件系统资源管理器

安装项目需要部署 ExcelAddIn。 可以通过将 ExcelAddIn 项目输出添加到安装项目来配置此任务的安装项目。

添加 ExcelAddIn 项目输出

  1. 解决方案资源管理器中,右键单击办公室AddInSetup,单击“添加”,然后单击项目输出”。

  2. “添加项目输出组 ”对话框中, 从项目列表中选择 ExcelAddIn ,然后选择 “主输出”。

  3. 单击“确定将项目输出添加到安装项目。

    Screenshot of the Setup Project Add Project Output Group dialog

    图 2:设置项目“添加项目输出组”对话框

安装项目需要部署部署清单和应用程序清单。 将这两个文件作为 ExcelAddIn 项目的输出文件夹中的独立文件添加到安装项目。

添加部署和应用程序清单

  1. 解决方案资源管理器中,右键单击办公室AddInSetup,单击“添加,然后单击“文件”。

  2. “添加文件 ”对话框中,导航到 ExcelAddIn 输出目录。 输出目录 通常是项目根目录的 bin\release 子文件夹,具体取决于所选生成配置。

  3. 选择 ExcelAddIn.vstoExcelAddIn.dll.manifest 文件,然后单击“打开将这两个文件添加到安装项目。

    Screenshot of the Application and deployment manifests in Solution Explorer

    图 3:外接程序解决方案资源管理器的应用程序和部署清单

引用 ExcelAddIn 包括 ExcelAddIn 所需的所有组件。 必须使用先决条件包排除和部署这些组件,以便正确注册这些组件。 此外,在安装开始之前,必须显示并接受软件许可条款。

排除 ExcelAddIn 项目依赖项

  1. 在解决方案资源管理器的 办公室AddInSetup 节点中,选择“检测到的依赖项”项下的所有依赖项项,但 Microsoft .NET Framework 或任何以 *结尾的程序集除外。Utilities.dll。 实用工具程序集应与应用程序一起部署。

  2. 右键单击该组,然后选择“ 属性”。

  3. “属性” 窗口中,将 Exclude 属性更改为 True ,以从安装项目中排除依赖程序集。 请确保不排除任何实用工具程序集。

    Screenshot of Solution Explorer showing the dependencies to exclude

    图 4:排除依赖项

可以通过添加安装程序(也称为引导程序)来配置 Windows Installer 包以安装必备组件。 此安装程序可以安装必备组件(称为引导过程)。

对于 ExcelAddIn,必须先安装这些先决条件,然后加载项才能正确运行:

  • 办公室解决方案面向的 Microsoft .NET Framework 版本。
  • Microsoft Visual Studio 2010 Tools for 办公室 Runtime。

将依赖组件配置为先决条件

  1. 解决方案资源管理器中,右键单击办公室AddInSetup 项目,然后选择“属性”。

  2. 此时会显示“办公室AddInSetup 属性页”对话框。

  3. 单击“先决条件”按钮。

  4. 在“先决条件”对话框中,选择正确版本的 .NET Framework 和 Microsoft Visual Studio Tools for 办公室 Runtime。

    Screenshot of the Prerequisites Dialog Box

    图 5:“先决条件”对话框

    注意

    Visual Studio 安装程序项目中配置的一些先决条件包依赖于所选的生成配置。 必须为使用的每个生成配置选择正确的必备组件。

Microsoft 办公室使用注册表项查找加载项。 HKEY_CURRENT_U标准版R 配置单元中的密钥用于为每个用户注册外接程序。 HKEY_LOCAL_MACHINE配置单元下的密钥用于为计算机的所有用户注册外接程序。 有关注册表项的详细信息,请参阅 VSTO 外接程序的注册表项。

配置注册表

  1. 解决方案资源管理器中,右键单击办公室AddInSetup

  2. 展开 视图

  3. 单击“注册表打开注册表编辑器窗口。

  4. 注册表(办公室AddInSetup)编辑器中,展开HKEY_LOCAL_MACHINE,然后单击软件

  5. 删除在 HKEY_LOCAL_MACHINE\Software找到的 [Manufacturer] 密钥。

  6. 展开 HKEY_CURRENT_U标准版R,然后选择“软件”。

  7. 删除在 HKEY_CURRENT_U标准版R\Software找到的 [Manufacturer] 密钥。

  8. 若要为外接程序安装添加注册表项,请 右键单击“用户/计算机 Hive ”键,选择“ 新建密钥”。 使用文本 软件 获取新密钥的名称。 右键单击新创建的软件密钥,并使用 Microsoft 文本创建新密钥。

  9. 使用类似的过程创建加载项注册所需的整个密钥层次结构:

    User/Machine Hive\Software\Microsoft\办公室\Excel\Addins\SampleCompany.ExcelAddIn

    公司名称通常用作外接程序名称的前缀,以提供唯一性。

  10. 右键单击 SampleCompany.ExcelAddIn 键,选择“新建,然后单击“字符串”值 使用名称的文本 说明

  11. 使用此步骤添加另外三个值:

    • String 类型的 FriendlyName
    • DWORD 类型的 LoadBehavior
    • 字符串类型的清单
  12. 右键单击 注册表编辑器中的“说明” 值,然后单击“ 属性”窗口。 在 “属性”窗口中,输入 “值”属性的 Excel 演示 AddIn

  13. 注册表编辑器中选择 FriendlyName 键。 在 “属性”窗口中,将 Value 属性更改为 Excel 演示 AddIn

  14. 注册表编辑器中选择 LoadBehavior 密钥。 在 “属性”窗口中,将 Value 属性更改为 3。 LoadBehavior 的值 3 指示应在主机应用程序启动时加载加载项。 有关加载行为的详细信息,请参阅 VSTO 外接程序的注册表项。

  15. 注册表编辑器中选择清单 键。 在 “属性”窗口中,将 Value 属性更改为 file:///[TARGETDIR]ExcelAddIn.vsto|vstolocal

    Screenshot of the Registry Editor

    图 6:设置注册表项

    VSTO 运行时使用此注册表项查找部署清单。 [TARGETDIR] 宏将替换为安装加载项的文件夹。 宏将包含尾随 \ 字符,因此部署清单的文件名应为 ExcelAddIn.vsto,而不带 \ 字符。 vstolocal 后缀告知 VSTO 运行时外接程序应从此位置加载,而不是 ClickOnce 缓存。 删除此后缀将导致运行时将自定义项复制到 ClickOnce 缓存中。

警告

在 Visual Studio 中,应非常小心注册表编辑器。 例如,如果意外为错误的键设置了 DeleteAtUninstall,则可以删除注册表的活动部分,使用户计算机处于不一致甚至更糟的状态。

64 位版本的办公室将使用 64 位注册表配置单元查找加载项。若要在 64 位注册表配置单元下注册外接程序,安装程序项目的目标平台必须仅设置为 64 位。

  1. 解决方案资源管理器中选择 办公室AddInSetup 项目。
  2. 转到“属性”窗口,将 TargetPlatform 属性设置为 x64

为 32 位和 64 位版本的办公室安装加载项需要创建两个单独的 MSI 包。 一个用于 32 位,一个用于 64 位。

Screenshot of the Properties Window showing the Target Platform for registering Add-ins with 64-bit Office

图 7:使用 64 位办公室注册外接程序的目标平台

如果 MSI 包用于安装外接程序或解决方案,则无需安装所需的必备组件即可进行安装。 可以使用 MSI 中的启动条件阻止加载项安装(如果未安装先决条件)。

配置启动条件以检测 VSTO 运行时

  1. 解决方案资源管理器中,右键单击办公室AddInSetup

  2. 展开 视图

  3. 单击“ 启动条件”。

  4. “启动条件”(办公室AddInSetup)编辑器中,右键单击目标计算机上的要求,然后单击“添加注册表启动条件”。 此搜索条件可以搜索注册表中 VSTO 运行时安装的密钥。 然后,通过命名属性向安装程序的各个部分提供键的值。 启动条件使用搜索条件定义的属性来检查特定值。

  5. “启动条件”(办公室AddInSetup)编辑器中,选择“搜索 RegistryEntry1”搜索条件,右键单击条件,然后选择“属性”窗口

  6. “属性” 窗口中,设置以下属性:

    1. 将“名称”的值设置为“搜索 VSTO 2010 运行时”。
    2. 将属性的值更改为 VSTORUNTIMEREDIST
    3. 将 RegKey 的值设置为 SOFTWARE\Microsoft\VSTO Runtime Setup\v4R
    4. Root 属性设置为 vsdrrHKLM
    5. Value 属性更改为 Version
  7. “启动条件”(办公室AddInSetup)编辑器中,选择 Condition1 启动条件,右键单击条件,然后选择“属性”窗口

  8. 在 “属性” 窗口中,设置以下属性:

    1. (名称) 设置为 验证 VSTO 2010 运行时可用性

    2. 将条件的值更改为 VSTORUNTIMEREDIST>=“10.0.30319”

    3. InstallURL 属性留空。

    4. 未将消息设置为 Visual Studio 2010 Tools for 办公室 Runtime。请运行 Setup.exe 以安装外接程序

      Screenshot of the Properties Window for the Verify Runtime Availability launch condition

      图 8:验证运行时可用性启动条件的属性窗口

上述启动条件显式检查引导程序包安装 VSTO 运行时时是否存在 VSTO 运行时。

配置启动条件以检测办公室安装的 VSTO 运行时

  1. “启动条件”(办公室AddInSetup)编辑器中,右键单击“搜索目标计算机”,然后单击“添加注册表搜索”。

  2. 选择 “搜索 RegistryEntry1 搜索条件”,右键单击条件,然后选择“ 属性”窗口

  3. “属性” 窗口中,设置以下属性:

    1. 将“名称”的值设置为“搜索办公室 VSTO 运行时
    2. 将 Property 的值更改为 办公室Runtime
    3. 将 RegKey 的值设置为 SOFTWARE\Microsoft\VSTO Runtime Setup\v4
    4. Root 属性设置为 vsdrrHKLM
    5. Value 属性更改为 Version
  4. “启动条件”(办公室AddInSetup)编辑器中,选择前面定义的验证 VSTO 2010 运行时可用性启动条件,右键单击条件,然后选择“属性”窗口

  5. Condition 属性的值更改为 VSTORUNTIMEREDIST >=“10.0.30319” OR OFFICERUNTIME>=“10.0.21022”。 根据外接程序所需的运行时版本,版本号可能有所不同。

    Screenshot of the Properties Windows for the launch condition

    图 9:通过 Redist 或 办公室 启动条件验证运行时可用性的属性 Windows

如果外接程序面向 .NET Framework 4 或更高版本,则可以将引用的主互操作程序集(PIA)中的类型嵌入到 VSTO 程序集中。

若要检查通过执行以下步骤将互操作类型嵌入外接程序:

  1. 在 解决方案资源管理器 中展开引用节点
  2. 选择其中一个 PIA 引用,例如办公室
  3. 通过点击 F4 或从“程序集”上下文菜单中选择“属性”来查看属性窗口。
  4. 检查属性 “嵌入互操作类型”的值。

如果该值设置为 True,则嵌入类型,你可以跳到“生成安装项目部分。

有关详细信息,请参阅 类型等效和嵌入式互操作类型

配置启动条件以检测办公室 PIA

  1. “启动条件”(办公室AddInSetup)编辑器中,右键单击目标计算机上的“要求”,然后单击“添加 Windows Installer 启动条件”。 此启动条件通过搜索特定组件 ID 来搜索 办公室 PIA。

  2. 右键单击 “搜索 Component1 ”,然后单击“ 属性”窗口 以显示启动条件的属性。

  3. “属性”窗口中,设置以下属性:

    1. 将 (Name) 属性的值更改为“搜索办公室共享 PIA”
    2. 将 ComponentID 的值更改为正在使用的办公室组件的组件 ID。 可以在下表中找到组件 ID 列表,例如 {64E2917E-AA13-4CA4-BFFE-EA6EDA3AFCB4}
    3. 将 Property 属性的值更改为 HASSHAREDPIA
  4. “启动条件”(办公室AddInSetup)编辑器中,右键单击“条件1”,然后单击“属性”窗口以显示启动条件的属性。

  5. 更改 Condition1以下属性:

    1. 更改(名称)验证办公室共享 PIA 可用性
    2. 条件 更改为 HASSHAREDPIA
    3. 将 InstallUrl空。
    4. 消息 更改为 与 Excel 交互所需的组件不可用。请运行 setup.exe

    Screenshot of the Properties Window for the Verify Office Shared PIA launch condition

    图 10:验证办公室共享 PIA 启动条件的属性窗口

用于Microsoft 办公室的主互操作程序集的组件 ID

主互操作程序集 Office 2010 Office 2013 办公室 2013 (64 位) Office 2016 办公室 2016 (64 位)
Excel {EA7564AC-C67D-4868-BE5C-26E4FC2223FF} {C8A65ABE-3270-4FD7-B854-50C8082C8F39} {E3BD1151-B9CA-4D45-A77E-51A6E0ED322A} {C845E028-E091-442E-8202-21F596C559A0} {C4ACE6DB-AA99-401F-8BE6-8784BD09F003}
InfoPath {4153F732-D670-4E44-8AB7-500F2B576BDA} {0F825A16-25B2-4771-A497-FC8AF3B355D8} {C5BBD36E-B320-47EF-A512-556B99CB7E41} - -
Outlook {1D844339-3DAE-413E-BC13-62D6A52816B2} {F9F828D5-9F0B-46F9-9E3E-9C59F3C5E136} {7824A03F-28CC-4371-BC54-93D15EFC1E7F} {2C6C511D-4542-4E0C-95D0-05D4406032F2} {7C6D92EF-7B45-46E5-8670-819663220E4E}
PowerPoint {企业版CBA6B8-3A62-44AD-99EB-8666265466F9} {813139AD-6DAB-4DDD-8C6D-0CA30D073B41} {05758318-BCFD-4288-AD8D-81185841C235} {9E73CEA4-29D0-4D16-8FB9-5AB17387C960} {E0A76492-0FD5-4EC2-8570-AE1BAA61DC88}
Visio {3EA123B5-6316-452E-9D51-A489E06E2347} {C1713368-12A8-41F1-ACA1-934B01AD6企业版B} {2CC0B221-22D2-4C15-A9FB-DE818E51AF75} {A4C55BC1-B94C-4058-B15C-B9D4AE540AD1} {2D4540EC-2C88-4C28-AE88-2614B5460648}
Word {8B74A499-37F8-4DEA-B5A0-D72FC501CEFA} {9FE736B7-B1企业版-410C-8D07-082891C3DAC8} {13C07AF5-B206-4A48-BB5B-B8022333E3CA} {30CAC893-3CA4-494C-A5E9-A99141352216} {DC5CCACD-A7AC-4FD3-9F70-9454B5DE5161}
Microsoft Forms 2.0 {B2279272-3FD2-434D-B94E-E4E0F8561AC4} {B2279272-3FD2-434D-B94E-E4E0F8561AC4} {A5A30117-2D2A-4C5C-B3C8-8897AC32C2AC} - -
Microsoft Graph {011B9112-EBB1-4A6C-86CB-C2FDC9EA7B0E} {52DA4B37-B8EB-4B7F-89C1-824654CE4C70} {24706F33-F0CE-4EB4-BC91-9E935394F510} - -
智能标记 {7102C98C-EF47-4F04-A227-FE33650BF954} {487A7921-EB3A-4262-BB5B-A5736B732486} {74EFC1F9-747D-4867-B951-EFCF29F51AF7} - -
共享办公室 {64E2917E-AA13-4CA4-BFFE-EA6EDA3AFCB4} {6A174BDB-0049-4D1C-86EF-3114CB0C4C4E} {76601EBB-44A7-49企业版-8DE3-7B7B9D7EBB05} {68477CB0-662A-48FB-AF2E-9573C92869F7} {625F5772-C1B3-497E-8ABE-7254EDB00506}
Project {957A4EC0-E67B-4E86-A383-6AF7270B216A} {1C50E422-24FA-44A9-A120-E88280C8C341} {706D7F44-8231-489D-9B25-3025ADE9F114} {0B6EDA1D-4A15-4F88-8B20-EA6528978E4E} {107BCD9A-F1DC-4004-A444-33706FC10058}

Screenshot of the Final launch conditions

图 11:最终发射条件

可以进一步优化 ExcelAddIn 安装的启动条件。 例如,如果安装了实际目标办公室应用程序,则检查可能很有用。

生成安装项目

  1. 解决方案资源管理器中,右键单击 办公室AddInSetup 项目,然后单击“生成”。
  2. 使用 Windows 资源管理器,导航到 办公室AddInSetup 项目的输出目录,并转到“发布”或“调试”文件夹,具体取决于所选生成配置。 将所有文件从文件夹复制到用户可以访问的位置。

测试 ExcelAddIn 设置

  1. 导航到办公室AddInSetup 复制到的位置。
  2. 双击 setup.exe 文件以安装 办公室AddInSetup 外接程序。 接受显示的任何软件许可条款,并完成安装向导以在用户计算机上安装加载项。

Excel 办公室解决方案应从安装期间指定的位置安装和运行。

文档级解决方案的其他要求

部署文档级解决方案需要在 Windows Installer 安装项目中执行几个不同的配置步骤。

下面是部署文档级解决方案所需的基本步骤列表:

  • 创建 Visual Studio 安装程序项目。
  • 添加文档级解决方案的主要输出。 主输出还包括Microsoft 办公室文档。
  • 将部署和应用程序清单添加为松散文件。
  • 从安装程序包中排除依赖组件(除任何实用工具程序集除外)。
  • 配置必备包。
  • 配置启动条件。
  • 生成安装项目并将结果复制到部署位置。
  • 通过执行安装程序,在用户计算机上部署文档级解决方案。
  • 根据需要更新自定义文档属性。

更改已部署文档的位置

办公室文档中的属性用于查找文档级别解决方案。 如果将文档安装到 VSTO 程序集所在的同一文件夹中,则无需更改。 但是,如果安装到不同的文件夹,则需要在安装过程中更新这些属性。

有关这些文档属性的详细信息,请参阅 自定义文档属性概述

若要更改这些属性,需要在安装过程中使用自定义操作。

以下示例使用名为 ExcelWorkbookProject 的文档级解决方案和名为 ExcelWorkbookSetup 的安装项目。 ExcelWorkbookSetup 项目使用上述相同步骤进行配置,但设置注册表项除外。

将自定义操作项目添加到 Visual Studio 解决方案

  1. 通过右键单击解决方案资源管理器中的办公室文档部署项目,将新的 .NET 控制台项目添加到解决方案

  2. 展开 “添加 ”并单击“ 新建项目”。

  3. 选择控制台应用模板并命名项目 AddCustomizationCustomAction

    Screenshot of the Solution Explorer - AddCustomizationCustomAction

    图 12:解决方案资源管理器 - AddCustomizationCustomAction

  4. 添加对这些程序集的引用:

    1. System.ComponentModel
    2. System.Configuration.Install
    3. Microsoft.VisualStudio.Tools.Applications
    4. Microsoft.VisualStudio.Tools.Applications.ServerDocument
  5. 将此代码复制到 Program.cs 或 Program.vb

    using System;
    using System.IO;
    using System.Collections;
    using System.ComponentModel;
    using System.Configuration.Install;
    using Microsoft.VisualStudio.Tools.Applications;
    using Microsoft.VisualStudio.Tools.Applications.Runtime;

    namespace AddCustomizationCustomAction
    {
        [RunInstaller(true)]
        public class AddCustomizations : Installer
        {
            public AddCustomizations() : base() { }

            public override void Install(IDictionary savedState)
            {
                base.Install(savedState);

                //Get the CustomActionData Parameters
                string documentLocation = Context.Parameters.ContainsKey("documentLocation") ? Context.Parameters["documentLocation"] : String.Empty;
                string assemblyLocation = Context.Parameters.ContainsKey("assemblyLocation") ? Context.Parameters["assemblyLocation"] : String.Empty;
                string deploymentManifestLocation = Context.Parameters.ContainsKey("deploymentManifestLocation") ? Context.Parameters["deploymentManifestLocation"] : String.Empty;
                Guid solutionID = Context.Parameters.ContainsKey("solutionID") ? new Guid(Context.Parameters["solutionID"]) : new Guid();

                string newDocLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Path.GetFileName(documentLocation));

                try
                {
                    //Move the file and set the Customizations
                    if (Uri.TryCreate(deploymentManifestLocation, UriKind.Absolute, out Uri docManifestLocationUri))
                    {
                        File.Move(documentLocation, newDocLocation);
                        ServerDocument.RemoveCustomization(newDocLocation);
                        ServerDocument.AddCustomization(newDocLocation, assemblyLocation,
                                                        solutionID, docManifestLocationUri,
                                                        true, out string[] nonpublicCachedDataMembers);
                    }
                    else
                    {
                        LogMessage("The document could not be customized.");
                    }
                }
                catch (ArgumentException)
                {
                    LogMessage("The document could not be customized.");
                }
                catch (DocumentNotCustomizedException)
                {
                    LogMessage("The document could not be customized.");
                }
                catch (InvalidOperationException)
                {
                    LogMessage("The customization could not be removed.");
                }
                catch (IOException)
                {
                    LogMessage("The document does not exist or is read-only.");
                }
            }

            public override void Rollback(IDictionary savedState)
            {
                base.Rollback(savedState);
                DeleteDocument();
            }
            public override void Uninstall(IDictionary savedState)
            {
                base.Uninstall(savedState);
                DeleteDocument();
            }
            private void DeleteDocument()
            {
                string documentLocation = Context.Parameters.ContainsKey("documentLocation") ? Context.Parameters["documentLocation"] : String.Empty;

                try
                {
                    File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Path.GetFileName(documentLocation)));
                }
                catch (Exception)
                {
                    LogMessage("The document doesn't exist or is read-only.");
                }
            }
            private void LogMessage(string Message)
            {
                if (Context.Parameters.ContainsKey("LogFile"))
                {
                    Context.LogMessage(Message);
                }
            }

            static void Main() { }
            }
    }

若要向文档添加自定义项,需要具有 VSTO 文档级解决方案的解决方案 ID。 此值是从 Visual Studio 项目文件中检索的。

检索解决方案 ID

  1. “生成”菜单上,单击“生成解决方案以生成文档级解决方案,并将解决方案 ID 属性添加到项目文件。

  2. 解决方案资源管理器中,右键单击文档级项目 ExcelWorkbookProject

  3. 单击 UnloadProject 从 Visual Studio 内部访问项目文件。

    Screenshot of Solution Explorer Unloading Excel Document Solution

    图 13:卸载 Excel 文档解决方案

  4. 解决方案资源管理器中,右键单击 ExcelWorkbookProject,然后单击 EditExcelWorkbookProject.vbprojEdit ExcelWorkbookProject.csproj

  5. ExcelWorkbookProject 编辑器中,找到 PropertyGroup 元素内的 SolutionID 元素。

  6. 复制此元素的 GUID 值。

    Retrieving the SolutionID

    图 14:检索 SolutionID

  7. 解决方案资源管理器中,右键单击 ExcelWorkbookProject,然后单击“重新加载项目”。

  8. 在出现的对话框中单击“是以关闭 ExcelWorkbookProject 编辑器。

  9. 解决方案 ID 将在“安装自定义操作”中使用。

最后一步是为安装和卸载步骤配置自定义操作

配置安装项目

  1. 解决方案资源管理器中,右键单击 ExcelWorkbookSetup,展开“添加”并单击“项目输出”。

  2. “添加项目输出组 ”对话框中的 “项目” 列表中,单击“ AddCustomizationCustomAction”。

  3. 选择“主输出”,然后单击“确定关闭对话框,并将包含自定义操作的程序集添加到安装项目。

    Screenshot of the Document Manifest Custom Action - Add Project Output Group window

    图 15:文档清单自定义操作 - 添加项目输出组

  4. 解决方案资源管理器中,右键单击 ExcelWorkbookSetup

  5. 展开 视图 并单击“ 自定义操作”。

  6. 自定义操作(ExcelWorkbookSetup) 编辑器中,右键单击 “自定义操作 ”,然后单击“ 添加自定义操作”。

  7. “项目 中的选择项”对话框中的 “查找范围 ”列表中,单击“ 应用程序文件夹”。 从 AddCustomizationCustomAction 中选择主输出(活动),然后单击“确定将自定义操作添加到“安装”步骤。

  8. “安装”节点下,右键单击 AddCustomizationCustomIzationCustomAction(Active)的主输出,然后单击“ 重命名”。 将自定义操作 “复制文档”命名为“我的文档”并附加自定义项。

  9. “卸载”节点下,右键单击 AddCustomizationCustomAction(Active) 的主输出,然后单击“ 重命名”。 将自定义操作 命名为“文档”文件夹中的“删除文档”。

    Screenshot of the Document Manifest Custom Actions window

    图 16:文档清单自定义操作

  10. “自定义操作”(ExcelWorkbookSetup) 编辑器中,右键单击“ 将文档复制到我的文档”,然后附加自定义 项,然后单击“ 属性”窗口

  11. CustomActionData属性窗口中,输入自定义 DLL 的位置、部署清单和Microsoft 办公室文档的位置。 还需要 SolutionID。

  12. 如果要将任何安装错误记录到文件中,请包括 LogFile 参数。 s

    /assemblyLocation="[INSTALLDIR]ExcelWorkbookProject.dll" /deploymentManifestLocation="[INSTALLDIR]ExcelWorkbookProject.vsto" /documentLocation="[INSTALLDIR]ExcelWorkbookProject.xlsx" /solutionID="Your Solution ID" /LogFile="[TARGETDIR]Setup.log"
    

    Screenshot of the Custom Action to Copy Document to My Documents Properties window

    图 17:将文档复制到“我的文档”的自定义操作

  13. 用于卸载的自定义操作需要文档的名称,可以使用 CustomActionData 中的 同一 documentLocation 参数提供该名称

    /documentLocation="[INSTALLDIR]ExcelWorkbookProject.xlsx"
    
  14. 编译并部署 ExcelWorkbookSetup 项目。

  15. “我的文档 ”文件夹中查找并打开 ExcelWorkbookProject.xlsx 文件。

其他资源

如何:安装 Visual Studio Tools for 办公室 Runtime

Office Primary Interop Assemblies

VSTO 外接程序的注册表项

Custom Document Properties Overview

在 Windows 注册表中指定窗体区域

Granting Trust to Documents

关于作者

Wouter van Vugt 是一个 Microsoft MVP,拥有 办公室 Open XML 技术,也是一位独立顾问,专注于使用 SharePoint、Microsoft 办公室和相关 .NET 技术创建办公室业务应用程序(OBA)。 Wouter 是开发人员社区网站(如 MSDN)的频繁参与者。 他出版了几篇白皮书和文章,以及一本名为 Open XML:解释电子书的行上提供的书籍。 Wouter 是代码顾问的创始人,该公司是一家荷兰公司,专注于通过各种渠道交付尖端技术内容。 你可以阅读他的博客来了解有关 Wouter 的更多信息。

泰德·帕蒂森是 SharePoint MVP、作者、教练和泰德·帕蒂森集团的创始人。 2005年秋季,Ted 被 Microsoft 开发人员平台福音派团队雇用,创作 Windows SharePoint Services 3.0 的 Ascend 开发人员培训课程,并Microsoft 办公室 SharePoint Server 2007。 此后,Ted 一直专注于教育专业开发人员使用 SharePoint 2007 技术。 Ted 已经为名为 Windows SharePoint Services 3.0 的 Microsoft Press 撰写了一本名为“内部 Windows SharePoint Services 3.0”的书籍,重点介绍如何将 SharePoint 用作构建业务解决方案的开发平台。 Ted 还为名为“办公室 Space”的 MSDN 杂志编写了一个以开发人员为中心的专栏。