用户驱动安装 - 开发人员指南

用户驱动安装 (UDI) 可帮助简化使用 Microsoft System Center 2012 R2 Configuration Manager 中的操作系统部署 (OSD) 功能将 Windows® 客户端操作系统(例如Windows 8.1 ®)部署到计算机。 UDI 是 Microsoft 部署工具包 (MDT) 的一部分。

简介

通常,在使用 OSD 功能部署操作系统时,必须提供部署操作系统所需的所有信息。 此信息在配置文件或数据库 ((如 CustomSettings.ini 文件或 MDT 数据库 [MDT DB] ) )中配置。 必须先提供所有配置设置,然后才能启动部署。

UDI 提供了一个向导驱动的接口,允许你在执行部署之前立即提供配置信息。 此行为允许创建通用 OSD 任务序列,然后在部署时提供特定于计算机的信息,从而在部署过程中提供更大的灵活性。

目标受众

本指南面向为 UDI 向导创建自定义向导页的开发人员,以及为 UDI 向导设计器创建自定义向导页编辑器的开发人员。 本指南假定你熟悉以下方法的 Windows 应用程序开发:

  • C++,用于创建自定义向导页

  • Microsoft .NET Framework,用于创建自定义向导页编辑器

  • Windows Presentation Foundation (WPF) ,用于创建自定义向导页编辑器

  • WPF 支持的语言,例如 C#、C++或 Microsoft Visual Basic® .NET,用于创建自定义向导页编辑器

关于本指南

本指南提供了必要的参考信息,可帮助你为组织自定义 UTI。 本指南不讨论管理或操作主题,例如安装包含 UDI) 的 MDT (、配置 UDI 以部署操作系统和应用程序,或使用 UDI 向导执行部署。 有关这些主题的详细信息,请参阅使用 MDT 随附的 Microsoft 部署工具包中的 UDI 主题。

UDI 开发概述

UDI 开发允许扩展 UDI 提供的功能。 通常,如果要收集 UDI 部署过程使用的其他信息,则需要进行 UDI 开发。 此附加信息通常保存为任务序列变量,任务序列步骤在 UDI 任务序列中Configuration Manager读取。

UDI 体系结构

UDI 开发的高级目标是创建可在 UDI 向导中显示的自定义向导页。 通过创建自定义向导页,可以扩展 UDI 的现有功能,以满足组织的业务和技术要求。 自定义向导页除了收集或取代 UDI 提供的向导页之外,还会收集信息。

图 1 说明了 UDI 向导设计器与 UDI 向导之间的关系。

图 1.UDI 向导与 UDI 向导设计器之间的关系 图 1。 UDI 向导与 UDI 向导设计器之间的关系

图 1. UDI 向导与 UDI 向导设计器之间的关系

在概念层面,UDI 开发包括创建:

  • 自定义向导页。 向导页显示在 UDI 向导中,并收集完成部署过程所需的信息。 使用 Microsoft Visual Studio® 中的 C++ 创建向导页。 自定义向导页实现为 UDI 向导读取的 DLL。 UDI 软件开发工具包 (SDK) 包含如何创建自定义向导页的示例。

  • 自定义向导页面编辑器。 使用向导页编辑器配置自定义向导页的行为。 自定义向导页编辑器实现为 UDI 向导设计器读取的 DLL。 使用以下方法创建向导页编辑器:

    • WPF 版本 4.0

    • Microsoft Prism 版本 4.0

    • Microsoft Unity 应用程序块 (Unity) 版本 2.1

      MDT 包括创建自定义向导页编辑器所需的所有程序集,以便在 UDI 向导设计器中使用。 UDI SDK 包含如何创建自定义向导页编辑器的示例。

    此外,UDI 向导设计器使用支持向导页编辑器配置文件。 在创建自定义向导页和自定义向导页编辑器的过程中,可以创建向导页编辑器配置文件。 UDI 向导设计器在 UDI 向导配置文件和相应的 .app 文件中创建必要的 XML 信息。

准备 UDI 开发环境

在开始创建自己的自定义向导页和向导页编辑器之前,请执行以下步骤来准备 UDI 开发环境:

  1. 按照准备 UDI 开发环境先决条件中所述准备 UDI 开发环境先决条件

  2. 按照配置 UDI 开发环境中所述 配置 UDI 开发环境

  3. 验证是否正确配置了 UDI 开发环境,如 验证 UDI 开发环境中所述。

准备 UDI 开发环境先决条件

若要准备 UDI 开发环境先决条件,请执行以下步骤:

  1. 按照准备 UDI 开发环境硬件先决条件中所述准备 UDI 开发环境硬件性能

  2. 按照准备 UDI 开发环境软件先决条件中所述准备 UDI 开发环境软件性能

准备 UDI 开发环境硬件先决条件

UDI 开发环境硬件先决条件与所使用的 Microsoft Visual Studio 版本的硬件要求相同。 有关这些要求的详细信息,请参阅 Visual Studio 文档中每个版本的系统要求。

准备 UDI 开发环境软件先决条件

UDI 开发环境具有以下软件先决条件:

  • 建议使用 Visual Studio 2010 支持的任何 Windows 操作系统 (Windows 7 或 Windows Server® 2008 R2。)

    你需要一个支持要开发的处理器体系结构的 Windows 操作系统。 可以使用 64 位操作系统执行 32 位和 64 位 UDI 开发。 你仅在 32 位操作系统上执行 32 位 UDI 开发。 因此,应使用 64 位操作系统。

    注意

    UDI 开发环境不支持 Windows 操作系统的 IntelItanium 版本 (IA-64) 。

    有关 Visual Studio 2010 支持的操作系统的详细信息,请参阅 Visual Studio 文档中每个版本的系统要求。

  • Visual Studio 2010) 要求Microsoft .NET Framework版本 4.0 (

  • C++ 语言 (扩展 UDI 向导页时使用的语言)

  • WPF 支持的其他语言,如 C#、Visual Basic .NET 或 C++/公共语言基础结构,它们用于扩展 UDI 向导设计器向导页编辑器

    注意

    UDI 向导设计器页编辑器的示例源代码是用 C# 编写的。 如果要使用示例源代码,请安装 C# 语言。

配置 UDI 开发环境

满足 UDI 开发环境先决条件后,请执行以下步骤来配置 UDI 开发环境:

  1. 安装 Visual Studio 2010。

    确保安装 C++ 语言和 WPF 支持的任何其他语言。

    注意

    UDI 向导编辑器页面的示例源代码是用 C# 编写的。 如果要使用示例源代码,请安装 C# 语言。

    有关安装 Visual Studio 2010 的详细信息,请参阅 安装 Visual Studio

  2. 安装 MDT。

    有关如何安装 MDT 的详细信息,请参阅 MDT 文档中使用 Microsoft 部署工具包中的“安装或升级到 MDT”部分。

  3. 在 Windows 资源管理器中创建 local_folder (,其中local_folder 是开发计算机上的本地驱动器上的任何文件夹) 。

  4. installation_folder\SDK 文件夹复制到 local_folder (其中 installation_folder 是安装 MDT 的文件夹, local_folder 是开发计算机上的本地驱动器上) 的任何文件夹。

    将 SDK 文件夹复制到另一个位置,因为 MDT 安装在 Program Files 文件夹中,如果没有提升的权限,则无法将其写入。 将 SDK 文件夹复制到其他位置后,无需提升权限即可修改 SDK 文件夹中的文件。

  5. “installation_folder\Templates\Distribution\Tools”文件夹复制到 local_folder (其中 installation_folder 是安装 MDT 的文件夹, local_folder 是在进程) 之前创建的文件夹。

  6. local_folder\Tools 文件夹重命名为 local_folder\OSDSetupWizard (其中 local_folder 是之前在进程) 中创建的文件夹。

    完成后, local_folder 下的文件夹结构应类似于图 2 所示的文件夹结构, (其中 local_folder 是之前在过程中创建的文件夹,在图) 中显示为 UDIDevelopment

    图 2.UDI 开发的文件夹结构 图 2。 用于 UDI 开发的文件夹结构

    图 2. 用于 UDI 开发的文件夹结构

验证 UDI 开发环境

配置 UDI 开发环境后,通过确保示例项目在 Visual Studio 2010 中正确生成,验证 UDI 开发环境是否已正确配置。

通过确定是否确定以下操作,验证 UDI 开发环境是否已正确配置:

验证 SamplePage 项目生成是否正确

SamplePage 项目提供了如何为 UDI 向导创建自定义向导页的示例。 有关 SamplePage 项目的详细信息,请参阅 查看 SamplePage Visual Studio 解决方案

验证 SamplePage 项目是否正确生成

  1. 启动 Visual Studio 2010。

  2. 打开 SamplePage 项目。

    SamplePage 项目位于 local_folder\SDK\UDI\SamplePage 文件夹中, (其中local_folder 是之前在进程) 中创建的文件夹。

  3. 在 Visual Studio 2010 Průzkumník řešení 中,右键单击 SamplePage 项目,然后单击“属性”。

    此时将显示 “SamplePage 属性页 ”对话框。

  4. “SamplePage 属性页 ”对话框中,转到“配置属性/调试”。

  5. 在“调试属性”中的 “配置”下,选择“ 所有配置”。

  6. 在“调试”属性的 “命令”下,键入 $ (TargetDir) \OSDSetupWizard.exe。

  7. 在“调试”属性的 “工作目录”下,键入 $ (TargetDir)

  8. “SamplePage 属性页 ”对话框中,转到“配置属性/生成事件/生成后事件”。

  9. 在“生成后事件”属性的 “命令行”下,键入以下内容:

    copy /y "$(ProjectDir)..\..\..\..\OSDSetupWizard\x86\*.*" "$(TargetDir)"  
    xcopy /y /i "$(ProjectDir)..\..\..\..\OSDSetupWizard\x86\en-us" "$(TargetDir)en-us"  
    copy /y "$(ProjectDir)..\..\..\..\OSDSetupWizard\OSDResults\Images\UDI_Wizard_Banner.bmp" "$(ProjectDir)header.bmp"  
    copy /y "$(ProjectDir)Config.xml" "$(TargetDir)"  
    copy /y "$(ProjectDir)header.bmp" "$(TargetDir)header.bmp"  
    
  10. “SamplePage 属性页 ”对话框中,单击“ 确定”。

  11. 保存项目。

  12. “调试” 菜单中,单击“ 开始调试”。

    此时会显示“Microsoft Visual Studio”对话框,指示源已过期,并询问是否要生成项目。

  13. “Microsoft Visual Studio”对话框中,单击“”。

    此时会显示“ 无调试信息 ”对话框,告知你没有可用于OSDSetupWizard.exe的调试信息。

  14. 在“ 无调试信息 ”对话框中,单击“ ”。

    UDI 向导随即打开,并显示自定义向导页。

  15. 验证是否可以在“ 选择位置”中选择一个值。

  16. 包含示例页的向导 窗体中,单击“ 取消”。

    此时会显示 “取消向导 ”对话框。

  17. “取消向导 ”对话框中,单击“ ”。

  18. 关闭 Visual Studio 2010。

验证 SampleEditor 项目生成是否正确

SampleEditor 项目提供了如何为 UDI 向导设计器创建自定义向导页编辑器的示例。 有关 SampleEditor 项目的详细信息,请参阅 查看 SamplePage Visual Studio 解决方案

验证 SampleEditor 项目生成是否正确

  1. 启动 Visual Studio 2010。

  2. 打开 SampleEditor 项目。

    SampleEditor 项目位于 local_folder\SDK\UDI\SampleEditor 文件夹 (,其中 local_folder 是之前在进程) 中创建的文件夹。

  3. 在 Visual Studio 2010 的 Průzkumník řešení 中,选择 SampleEditor 项目。

  4. 在“ 项目 ”菜单中,单击“ 添加引用”。

    此时会打开“ 添加引用 ”对话框。

  5. 在“ 添加引用 ”对话框中,单击“ 浏览 ”选项卡。

  6. 在“ 浏览 ”选项卡上,转到 “installation_folder\Bin (其中 installation_folder 是安装 MDT) 的文件夹。 选择以下文件,然后单击“ 确定”:

    • Microsoft.Enterprise.UDIDesigner.Common.dll

    • Microsoft.Enterprise.UDIDesigner.DataService.dll

    • Microsoft.Enterprise.UDIDesigner.Infrastructure.dll

    • Microsoft.Practices.Prism.dll

    • Microsoft.Practices.ServiceLocation.dll

    • Microsoft.Practices.Unity.dll

    • RibbonControlsLibrary.dll

    注意

    单击文件时按住 Ctrl 键,可以在“ 浏览 ”选项卡上选择多个文件。

  7. 在 Průzkumník řešení 中,转到 SampleEditor/References。

  8. 验证这些引用是否没有任何警告或错误。

  9. 在“Průzkumník řešení”中,右键单击“SampleEditor”项目,然后单击“属性”。

    此时会显示“ SampleEditor 属性页 ”对话框。

  10. “SampleEditor 属性页 ”对话框中,单击“ 调试 ”选项卡。

  11. 在“ 调试 ”选项卡上,单击“ 启动外部程序”。

  12. “启动外部程序 ,键入installation_folder\Bin\UDIDesigner.exe(其中 installation_folder 是安装 MDT) 的文件夹,然后单击“ 确定”。

    提示

    可以单击省略号 (...) 按钮浏览到文件夹并选择“UDIDesigner.exe”。

  13. 在“ 文件 ”菜单中,单击“ 全部保存”。

  14. local_folder\SDK\SamplePage\SamplePage.dll.config 文件复制到 installation_folder\Bin\Config 文件夹 (其中 local_folder 是在配置过程之前在开发计算机上创建的文件夹,installation_folder 是安装 MDT) 的文件夹。

  15. 在 Visual Studio 2010 的“ 调试” 菜单中,单击“ 开始调试”。

    UDI 向导设计器启动。

  16. 在 UDI 向导设计器中,在功能区上,单击“ 打开”。

    此时会显示“ 打开 ”对话框。

  17. 在“ 打开 ”对话框中,打开 local_folder\SDK\SamplePage\SamplePage\Config.xml文件 (其中 local_folder 是在配置过程) 之前在开发计算机上创建的文件夹。

    Config.xml文件随即打开,详细信息窗格中会显示自定义 阶段组

  18. 在详细信息窗格中,单击“ 配置 ”选项卡。

  19. 查看“ 位置 ”框的配置信息,包括以下内容:

    • “已解锁 ”按钮,用于启用或禁用“ 位置 ”框

    • 默认值 框,在其中输入要显示在“ 位置 ”框中的默认值

    • 在摘要页中可见的友好显示名称,在其中输入 “摘要 ”页上显示的信息的标题

    • 位置 列表框,其中包括可能的位置列表

  20. 关闭 UDI 向导设计器。

  21. 关闭 Visual Studio 2010。

查看 UDI SDK 示例

在开始开发之前,请查看 UDI SDK 中提供的示例。 使用本指南中的信息和示例中的源代码来帮助创建自己的 UDI 自定义向导页和向导页编辑器。

查看以下代码,了解 UDI SDK 示例:

查看 SDK 文件夹的内容

在配置 UDI 开发环境期间,已将 SDK 文件夹从安装 MDT 的文件夹复制到创建的另一个文件夹。 表 1 列出了 SDK 文件夹正下方的文件夹,并提供了每个文件夹的简要说明。

表 1. UDI SDK 中的文件夹

Folder 此文件夹包含
Includes 为 UDI 向导创建自定义向导页所需的 C++ 头文件
将链接到自定义页面的 C++ 库文件;静态链接库有 32 位和 64 位版本。 注意: (IA-64) 库的 Itanium 版本不可用。
SampleEditor 用于生成自定义编辑器的 Visual Studio 项目,用于在 UDI 向导设计器中编辑 SamplePage 页,该页面以 C 编写#
SamplePage 用于生成自定义 UDI 向导页的 Visual Studio 项目,以 Visual C++ 编写

查看 SamplePage Visual Studio 解决方案

在开始创建自定义向导页和向导页编辑器之前,请执行以下任务来准备 UDI 开发环境:

查看向导页生命周期

UDI 向导页具有对应于页面生命周期的每个阶段 (或阶段) 的方法。 作为创建自定义向导页的一部分,需要使用代码替代这些方法。 表 2 列出了需要重写的方法,并提供了每个方法的简要说明,包括何时在向导页生命周期中使用 方法。

表 2. 向导页生命周期中的方法

方法 说明
OnWindowCreated 创建页面窗口后,将调用此方法一次。

对于此方法,请编写首次初始化页面且只需执行一次的代码。 例如,使用此方法初始化字段或从 UDI 向导配置文件中的 Setter 元素读取配置信息。
OnWindowShown 每次在 UDI 向导中显示页面 (显示) 时,都会调用此方法。 首次显示页面时,将调用它,每次导航到页面时,在向导中单击“ 下一步 ”或“ 上一步 ”。

对于此方法,请编写代码来准备要显示的页面,例如,读取内存变量、任务序列变量或环境变量,然后根据对这些变量所做的任何更改更新页面。
OnCommonControlEvent 每当显示向导页并接收来自子 (的WM_NOTIFY消息时,都可以调用此方法,通常常见控件) 。

对于此方法,请编写基于通知消息处理WM_NOTIFY的代码。 例如,你可能想要响应来自公共控件的事件,例如响应 TreeView 控件的单击或双击事件。
OnUnhandledEvent 每当向导页出现未经处理的窗口消息时,将调用此方法。 此方法提供了截获和处理这些未经处理的窗口消息的机会。

对于此方法,请编写用于处理与向导页相关的窗口消息的代码。 通常,无需重写此方法。
OnNextClicked 在向导中单击“ 下一步 ”时,将调用此方法。

对于此方法,请在转到下一个向导页(例如,执行可能需要很长时间的验证)之前编写执行任何必要操作的代码。 如果验证失败,可以取消 “下一步 ”请求并显示一条消息。
OnWindowHidden 每次显示上一个或下一个向导页时,都会调用此方法。

对于此方法,请编写代码,在隐藏页面之前,在显示另一个页面之前执行任何操作。 通常,无需重写此方法。

查看 SamplePage 示例

使用以下列表查看 SamplePage 示例,该列表表示 SamplePage 示例的向导页生命周期中的事件序列:

  1. UDI 向导OSDSetupWizard.exe从示例中的 UDI 向导配置文件读取配置信息, (Config.xml文件) ,如 步骤 1:UDI 向导 (OSDSetupWizard.exe) 读取Config.xml文件中所述。

  2. UDI 向导加载 UDI 向导配置文件中列出的每个向导页所需的 DLL,如 步骤 2:UDI 向导加载自定义向导页的 DLL 中所述。

  3. UDI 向导显示自定义向导页,并允许所需的控件交互,如 步骤 3:UDI 向导显示自定义向导页中所述。

  4. 当自定义向导页收集信息时,请在单击“下一步”页中单击“下一步”按钮中所述,先执行任何必要的任务,然后再单击下一个向导。

步骤 1:UDI 向导 (OSDSetupWizard.exe) 读取Config.xml文件

当 UDI 向导 (OSDSetupWizard.exe) 启动时,默认情况下,它会读取 UDI 向导配置文件,该文件是UDIWizard_Config.xml文件-UDI 向导的主配置文件。

注意

该示例使用 Config.xml 文件作为配置文件。 在 MDT 中,默认配置文件是 UDIWizard_Config.xml 文件,该文件位于用于配置的 MDT 文件包的 Scripts 文件夹中。

可以通过修改 UDI 向导任务序列步骤以使用 /definition 参数来替代 UDI 向导使用的默认配置文件。 有关重写 UDI 向导使用的默认配置文件的详细信息,请参阅“重写 UDI 向导使用的配置文件”。

Config.xml文件中的顶级元素是

  • DLL 元素

  • Style 元素

  • Pages 元素

  • StageGroups 元素

    有关 UDI 向导配置文件的架构以及其中每个元素的详细信息,请参阅 UDI 向导配置文件架构参考

    UDI 向导将扫描 DLL 元素,查找要加载的.dll文件。 在此示例中,列出了两个.dll文件:SamplePage.dll和SharedPages.dll。 这些.dll文件必须与 OSDSetupWizard.exe 位于同一文件夹中,其中 32 位版本的平台 (为 x86,64 位版本) 为 x64。

    UDI 向导扫描 Pages 元素,查找定义的页面。 在本示例中,定义了两个页面: CustomSummaryPagePage 元素的 Type 属性在 PageClassIDs.h 文件中定义,并唯一定义自定义页面的类型。

    在此示例中,定义的类型为Microsoft。SamplePage.LocationPage。 对于自定义页面,请替换以下内容,以避免与将来可能创建的其他页面发生任何潜在冲突:

  • 你的组织名称代替Microsoft

  • 项目名称代替 SamplePage

  • 自定义向导页名称代替 LocationPage

步骤 2:UDI 向导加载自定义向导页的 DLL

当 UDI 向导加载 DLL 时,它会调用 RegisterFactories 函数,该函数必须在 .dll 文件中实现。 在此示例中,此函数在 dllmain.ccp 文件中实现。 创建的每个向导页都必须实现 RegisterFactories 函数。

RegisterFactories 函数用于将向导页的工厂类注册到 UDI 向导的类工厂注册表。 类工厂 是可以创建另一个类的实例的类。 RegisterFactories 函数创建工厂类的新实例,并将该类传递给 UDI 向导的类工厂注册表,这使该工厂类可供向导使用。 UDI 向导查找使用与自定义向导页的 Page 元素的 Type 属性匹配的 ID 注册的工厂类。

在此示例中,在 PageClassIds.h 文件中,ID 定义为 ID_LocationMicrosoft。SamplePage.LocationPage,与 Config.xml 文件中 Page 元素的 Type 属性匹配。 ID_Location 作为参数在 dllmain.ccp 文件中实现的 RegisterFactories 函数中传递。

可以使用 Register_name 函数模板创建函数,以简化新工厂实例的创建并注册新创建的实例。 使用 Register 函数模板提供 的名称 值必须实现 iClassFactory 接口。 ClassFactoryImpl 类处理实现类工厂的大部分详细信息。

还可以使用 RegisterFactories 函数来注册任务类型和验证程序类型。 有关详细信息,请参阅:

注意

该示例仅包含并注册一个自定义向导页。 该示例不包括自定义任务或验证程序,因此不注册任何自定义任务或验证程序。

步骤 3:UDI 向导显示自定义向导页

示例中的自定义向导页在 LocationPage.cpp 文件中定义。 向导页派生自模板类,这些类提供页面具有的大部分功能。 所有向导页都应派生自 WizardPageImpl 模板类,该类实现 IWizardPage 接口。 每个向导页都可以根据页面的需求实现其他可选模板类和相应的接口。

WizardPageImpl 模板类具有多个有用的接口,可帮助你编写自定义向导页。 将 WizardPageImpl 模板类 实现为自定义向导页的基类。

有关可用项的列表:

  • 向导页的模板类,请参阅 向导页帮助程序类

  • 向导页模板类的接口,请参阅 向导页接口

    示例中的自定义向导页派生自 WizardPageImpl 模板类 ,并实现 IWizardPage 接口。 此外,自定义向导页实现 IFieldCallback 接口。 这两者都在 LocationPage.cpp 文件中实现。

    示例自定义向导页将替代以下方法:

  • OnWindowCreated。 示例向导页中的 OnWindowCreated 方法调用以下方法:

    • AddField。 此方法将 IDD_LOCATION_PAGE 资源中的 IDC_COMBO_LOCATION 框控件与 Config.xml 文件中名为 LocationData 元素相关联。

      除了 AddField 方法外,还可以使用 AddRadioGroupAddToGroup 方法来支持其他控件和行为。

      注意

      确保在调用 InitFields 方法之前调用 AddFieldAddRadioGroupAddToGroup 方法。

    • InitFields。 使用此方法初始化已添加到窗体的控件) (字段。 页面的指针是参数。 在此示例中,传递 了此 指针,该指针引用了当前页。

      注意

      若要支持使用此指针,除了 WizardPageImpl 模板类支持的接口外,还必须实现 IFieldCallback 接口。

      IFieldCallback 接口调用 SetFieldDefault 方法,该方法用于设置文本框和复选框控件以外的控件的默认值。 在此示例中, SetFieldDefault 方法基于在 Config.xml 文件中 Field 元素的 Default 元素中指定的默认值设置组合 框控件的初始 索引。

      OnWindowCreated 方法使用 IFormController 接口设置表单控制器。 有关设置窗体控制器的详细信息,请参阅 设置窗体

  • InitLocations。 此方法从 Config.xml 文件中的位置列表中填充组合框。 Confg.xml 文件的 Data 元素和子 DataItem 元素提供可能值的列表。

  • OnNextClicked。 此方法执行以下任务:

    • 使用 SaveFields 方法在组合框中选择的值汇报 TSLocation 任务序列变量

    • 使用 SaveFields 方法添加将在“摘要”页上显示的信息

步骤 4:在自定义向导页中单击“下一步”按钮

当用户完成自定义向导页上的字段时,单击“ 下一步”,这将调用 OnNextClicked 方法。 OnNextClicked 方法在继续下一个向导页之前执行任何必要的任务,例如记录自定义向导页上所做的任何配置更改。

对于示例自定义向导页, OnNextClicked 方法的替代在 LocationPage.ccp 文件中实现。 在示例自定义向导页的 OnNextClicked 方法中,将调用以下方法:

  1. InitSection。 此方法为“ 摘要 ”页上显示的摘要数据初始化标题 (标签标题) 。 通常,可以使用 DisplayName () 函数设置此值。 使用 SaveFields 方法保存与此标题关联的数据。

  2. SaveFields。 此方法将字段值保存到任务序列变量和 “摘要 ”页上显示的数据。

查看 SampleEditor Visual Studio 解决方案

在开始创建自己的自定义向导页和向导页编辑器之前,请执行以下步骤来准备 UDI 开发环境:

查看 UDI 向导设计器体系结构

UDI 向导设计器是使用 WPF、Prism 和 Unity 开发的。 UDI 设计器用于编辑 UDI 向导配置文件 (UDIWizard_Config.xml) ,UDI 向导 (OSDSetupWizard.exe) 在运行时读取该文件。 UDI 向导配置文件中的 Pages 元素包含页面列表,其中每个向导页都有单独的 Page 元素。

编辑向导页的配置设置时,UDI 向导设计器将加载与向导页类型对应的自定义页面编辑器。 自定义向导页编辑器开发为 WPF 用户控件。 自定义向导页编辑器页使用 模型-视图-视图模型模型 (MVVM) WPF 的设计模式。

MVVM 设计模式有助于分隔用户界面 (UI;演示) 所呈现的数据。 数据是 UDI 向导配置文件中 Page 元素 (示例) 中的 Config.xml 文件的外观,使用 IDataService 接口的 CurrentPage 属性访问该文件。

UDI 向导设计器使用 DependencyAttribute 基于 Unity 中的依赖项注入框架获取 对 DataService 类的访问权限。 有关 Unity 中依赖项插入框架的详细信息,请参阅 将一些生命注入应用程序 - 了解 Unity 应用程序块

查看 UDI 向导页的可配置组件

创建自定义向导页时,某些配置设置可能会在代码中设置,在编译页面后无法更改。 但是,对于其他配置设置,需要允许使用 UDI 向导设计器更改这些配置设置。

通常,要使用 UDI 向导设计器配置的配置设置将保存在 UDI 向导配置文件中, (示例) 中的 Config.xml 文件。 但是,如有必要,还可以创建自己的单独配置文件。 使用单独配置文件的一个示例是 UDIWizard_Config.xml.app 文件, 应用程序发现 任务和 ApplicationPage 向导页类型使用该文件。

下面是可以使用 UDI 向导设计器管理的典型配置设置的列表:

  • 字段。 使用字段允许用户提供输入。 字段在 UDI 向导配置文件 (UDIWizard_Config.xml) 中显示为 Field 元素,其中包含每个字段的配置设置。 相应的向导页编辑器需要提供使用 FieldElementControl 编辑字段的字段配置设置的方法。

  • Properties。 Setter 有助于为页面上的实体创建属性,例如 Page 元素中的页面、 Field 元素中的字段或 DataDataItem 元素中的数据。 在 Setter 元素中配置属性。 为要定义的每个属性添加单独的 Setter 元素。 使用 SetterControl 编辑属性,并使用其他控件配置其他 Setter 元素。

  • 数据。 数据用于存储信息,供向导页和其他组件使用。 可以使用 Data 或 DataItem 元素为页面或字段定义数据。 通过正确使用 Data 或 DataItem 元素,可以在平面或分层结构中定义数据。 SDK 示例中的Config.xml演示如何生成平面数据结构。

    创建的自定义向导页编辑器必须能够管理这些配置设置。

查看 EditorPage 示例

EditorPage 示例用于在 UDI 向导配置文件中配置 SamplePage 向导页的配置设置。 EditorPage 示例具有以下主要组件:

  • 用于配置 “位置 ”组合框设置的 UI

  • 用于在“ 位置”组合 框中显示的可能位置列表中添加或编辑位置的 UI

  • 从 UDI 向导配置文件中读取并保存到的配置设置

  • 支持其他组件的代码

    执行以下步骤,查看 Visual Studio 中的 EditorPage 示例:

  1. 按照查看向导页编辑器加载和初始化中所述,查看如何在 UDI 向导设计器中加载和初始化 SampleEditor向导页编辑器

  2. 查看用于编辑 LocationPageEditor.xaml 和 LocationPageEditor.xaml.cs 文件中 的位置组合框 的 UI,如 查看用于配置位置组合框的用户界面中所述。

  3. 查看用于在 AddEditLocationView.xaml 和 AddEditLocationView.xaml.cs 文件中向列表添加或编辑位置的 UI,如 查看用于修改可能位置列表的用户界面中所述。

  4. 查看用于管理 UDI 向导配置文件中保存的配置信息的代码,如 查看用于管理配置信息的代码中所述。

查看向导页面编辑器加载和初始化

自定义向导页编辑器由 UDI 向导设计器根据需要加载。 启动 UDI 向导设计器时,将加载 UDI 向导设计器配置文件。 UDI 向导设计器扫描 install_folder\Bin\Config 文件夹 (其中 install_folder 是安装 MDT 的文件夹的名称,) 具有.config文件扩展名的文件。

在配置 UDI 开发环境期间,已将 SamplePage.dll.confg 文件复制到 install_folder\Bin\Config 文件夹。 启动 UDI 向导设计器时,将找到并加载 SamplePage.dll.confg 文件。

UDI 向导设计器使用 SamplePage.dll.confg 文件中 Page 元素的以下属性来加载和初始化 EditorPage 示例:

  • DesignerAssembly。 此属性确定要加载的 DLL 的名称。 此 DLL 需要放置在与 UDIDesigner.exe 文件相同的文件夹中,该文件是 install_folder\Bin 文件夹 (其中 install_folder 是) 安装 MDT 的文件夹的名称。

  • DesignerType。 此属性是包含 WPF 用户控件的类的 Microsoft .NET 类型名称。

  • 类型。 使用此属性可配置 UDI 向导加载的自定义向导页的页面类型。 UDI 向导设计器使用此属性在 UDI 向导配置文件中找到相应的 Page 元素。

  • Dll。 使用此属性可在 UDI 向导配置文件中配置 DLL 元素,UDI 向导设计器会创建该文件。

  • 说明。 使用此属性提供有关向导页编辑器的信息。 此属性的值显示在 UDI 向导设计器的“ 添加新页 ”对话框中,该对话框用于将向导页添加到“页面库”。

  • DisplayName。 使用此属性可以提供 UDI 向导设计器中显示的自定义向导页的名称。 此属性的值显示在 UDI 向导设计器的“ 添加新页 ”对话框中,该对话框用于将向导页添加到“页面库”。

    在此示例中,SamplePage 自定义向导页的类型Microsoft。SamplePage.LocationPage,保存在 Config.xml 文件中。 Config.xml 文件驻留在 local_folder\SDK\SamplePage\SamplePage 文件夹中, (其中local_folder 是在配置过程) 之前在开发计算机上创建的文件夹。

查看用于配置位置组合框的用户界面

加载并初始化向导页编辑器时,当类型为 Microsoft 的页面时,将加载 SampleEditor 向导页编辑器。已编辑 SamplePage.LocationPage。 页面编辑器的 UI 存储在 LocationPageEditor.xaml 文件中。

如果检查“ 设计 ”选项卡上的 UI 和 XAML 选项卡上的代码,可以看到图形 UI 与可扩展应用程序标记语言中的元素和属性之间的关系, (XAML) 。

例如,如果查看 XAML 中的 Controls:FieldElementControl 元素,可以看到它与相应 UI 的布局的关系。 使用 Controls:FieldElementControl 元素定义 FieldElementControl 控件。

XAML 文件中的 绑定 参数将示例页编辑器中的字段与 UDI 向导配置文件中的信息绑定。 例如,以下代码将 “默认值 ”文本框与示例) 中的 UDI 向导配置文件 (Config.xml 中的 Default 元素相关联:

<TextBox Text="{Binding FieldData.DefaultValue,  
 UpdateSourceTrigger=PropertyChanged,  
 Mode=TwoWay}"/>  

有关详细信息,请参阅 如何:使数据可用于 XAML 中的绑定

使用 XAML 中的 Views:CollectionTControl.ColumnCollectionView 元素编辑网格视图中可用位置的列表。 使用 CollectionTControl 控件可显示网格视图,并将网格视图绑定到 UDI 配置文件中名为“位置”的 Data 元素。

查看用于修改可能位置列表的用户界面

用于修改可能位置列表的 UI 包括:

查看用于修改位置列表的上下文相关菜单和功能区按钮

在包含位置列表的列表框中右键单击时,将显示上下文相关菜单。 功能区具有相应的按钮,可用于执行相同的任务。 LocationPageEditor.xaml 文件中的 Views:CollectionsTControl 控件元素根据执行的操作和设置的属性定义调用的方法,如下所示:

  • SelectedItem。 当用户从列表中选择项时,会激活此数据绑定属性。 此属性绑定到视图模型中的 CurrentLocation 属性,该属性位于 LocationPageEditorViewModel.cs 文件中, 由 CollectionTControl 控件用来传递编辑或删除现有项时选择的项。

  • AddItemAction。 当用户从上下文相关菜单或功能区上的相应按钮单击 “添加项 ”选项时,将执行此操作。 视图模型中返回 AddLocationAction 对象的属性的数据绑定。 此对象是 AddLocationCallback 方法,位于 LocationPageEditorViewModel.cs 文件中,并在 AddEditLocationView.xaml 文件中显示对话框。

  • EditItemAction。 当用户单击上下文相关菜单中的 “编辑项” 选项时,将执行此操作。 视图模型中返回 EditLocationAction 对象的属性的数据绑定。 此对象是 EditLocationCallback 方法,位于 LocationPageEditorViewModel.cs 文件中,并在 AddEditLocationView.xaml 文件中显示对话框。

  • RemoveAction。 当用户单击上下文相关菜单中的“ 删除项 ”选项时,将执行此操作。 视图模型中返回 RemoveAction 对象的属性的数据绑定。 此对象是 EditLocationCallback 方法,位于 LocationPageEditorViewModel.cs 文件中,并显示确认删除位置的消息。

查看用于添加或编辑位置的对话框

如果将新位置添加到位置列表或编辑现有位置,则会在 AddEditLocationView.xaml 文件中显示一条消息。 使用 LocationPageEditorViewModel.cs 文件中的 ShowDialogWindow 窗口方法显示消息。

AddEditLocationView.xaml 文件中的 UI 包括:

  • 名为 DialogFrame 的对话框架,其中包括以下元素:

    • 使用对话框框架的 DialogTitle 属性配置的标题

    • “确定”按钮,该按钮将“已批准”属性的返回状态设置为 True (在 LocationPageEditorViewModel.cs 文件中的 AddLocationCallback 方法中检查返回状态,以确定用户是否单击了“确定”。)

    • “取消”按钮,它将“已批准”属性的返回状态设置为 False (在 LocationPageEditorViewModel.cs 文件中的 AddLocationCallback 方法中检查返回状态,以确定用户是否单击了 Cancel.)

  • WPF 元素,其中包含:

    • 使用 Content 属性配置的标签

    • 一个文本框,该文本框绑定到 UDI 配置文件中名为“位置的 Data 元素, (示例中的 Config.xml 文件)

查看用于管理配置信息的代码

自定义向导页的配置信息存储在 UDI 向导配置文件中,即:

  • UDI SDK 提供的示例中Config.xml文件 (此文件仅包含 example 的配置设置。)

  • MDT 提供的UDIWizard_Config.xml文件,存储在 installation_folder\Templates\Distribution\Scripts 文件夹 (其中 ,installation_folder 是安装 MDT) 的文件夹;此文件包含所有内置向导页和阶段的配置设置

    在 SampleEditor 示例中, Locations 例程有助于管理配置信息,位于 LocationPageEditorViewModel.cs 文件中。 Locations 例程从 UDI 向导配置文件返回位置列表。 具体而言,返回的列表包含 UDI 向导配置文件中每个 DataItem 元素的项。

创建自定义 UDI 向导页

创建自定义 UDI 向导页的高级过程如下:

  1. 创建 SamplePage 解决方案的副本作为起点。

  2. 将所需控件 (字段) 放在窗体上。

  3. 编写代码以在向导页加载 onWindowCreated 方法) (替代时执行相应任务,包括以下步骤:

    1. 初始化窗体。

    2. 读取内存变量、任务序列变量、环境变量或 XML 文件信息 (,例如 Setter 属性) 。

  4. 编写任何代码以在 OnWindowShown 方法) 显示页面 (重写时执行相应的任务,包括以下步骤:

    1. 在步骤 3 中加载页面时,根据读取的信息启用或禁用控件。

    2. 在步骤 3 中加载页面时,基于读取的信息更新控件,例如基于所读信息的控件填充。

  5. 编写任何代码以在用户与向导页交互时执行相应的任务。

  6. 编写任何代码以在 UDI 向导中单击“ 下一步 ”时执行相应的任务, (OnNextClicked 方法) 重写,包括以下步骤:

    1. 更新任何内存变量、任务序列变量、环境变量或 XML 文件信息。

    2. 如果) 页上的字段未执行, (更新摘要页信息。

  7. 生成解决方案。

    确保创建的 DLL 版本与安装 MDT 的处理器平台相同,具体而言,Windows 预安装环境的处理器平台 (Windows PE) 。 UDI 向导可在以下环境中运行:

    • 目标计算机上的现有操作系统。 可以在 32 位或 64 位 Windows 操作系统上运行 32 位版本的向导页。 但是,只能在 64 位 Windows 操作系统上运行 64 位版本的向导页。

    • 目标计算机上的 Windows PE。 Windows PE 不支持在 64 位版本的 Windows PE 上运行 32 位应用程序。 因此,你需要为计划使用的 Windows PE 的每个处理器体系结构生成一个向导页版本。

  8. 将自定义向导页的 DLL 复制到 installation_folder\Templates\Distribution\Tools\ 平台文件夹 (其中 installation_folder 是安装 MDT 的文件夹, 平台 是 32 位版本的 x86 或 64 位版本) 的 x64

  9. 完成创建自定义页面编辑器的步骤。

创建自定义向导页编辑器

创建自定义 UDI 向导页面编辑器的高级过程如下:

  1. 创建 SampleEditor 解决方案的副本作为起点。

  2. 在 .xaml 文件中创建主页面编辑器 UI。

  3. 根据需要,根据向导页的要求,添加要配置 (的 FieldElementControl 控件的实例) 。

  4. 根据需要,添加向导页所需的 SetterControl 控件实例,以便 (配置) 。

  5. 根据需要,添加向导页所需的 CollectionTControl 控件实例,以便 () 配置。

  6. 添加 IDataService 接口。

  7. 编写相应的代码,以根据要使用自定义向导页编辑器配置的配置设置更新 UDI 向导配置文件。

  8. 在 .xaml 文件中创建子对话框,并按照要配置的向导页的要求,使用 IMessageBoxService 接口从主页面编辑器调用它们。

  9. 根据要配置的向导页的要求,将适当的接口添加到 UDI 向导设计器功能区。

  10. 生成解决方案。

    注意

    确保创建的 DLL 版本与安装 MDT 的处理器平台相同。 例如,如果安装 64 位版本的 MDT,则生成 64 位版本的自定义页面编辑器。

  11. 创建 UDI 向导设计器配置文件以加载必要的 DLL,并将向导页编辑器与相应的向导页 () 示例中的 SamplePage.dll.config 文件映射。

    有关在向导页和向导页编辑器之间执行映射所需的元素的详细信息,请参阅 DesignerMappings 元素、子元素和相应的属性。

  12. 将上一步中创建的 UDI 向导设计器配置文件复制到 installation_folder\Bin\Config 文件夹 (其中 installation_folder 是安装 MDT 版本) 的文件夹。

  13. 将自定义向导页编辑器的 DLL 复制到 installation_folder\Bin 文件夹 (其中 installation_folder 是安装 MDT) 的文件夹。

创建自定义 UDI 任务

UDI 任务 是用 C++ 编写的 DLL,用于实现 ITask 接口。 通过创建 UDI 向导设计器配置文件 (.config 文件) 并将其放置在 installation_folder\Bin\Config 文件夹 (其中 ,installation_folder 是安装 MDT) 的文件夹,将 DLL 注册到 UDI 向导设计器任务库。

注意

可以在同一个.dll文件中创建包含向导页、任务和验证器的 DLL。 还可以创建单个 UDI 向导设计器配置文件 (.config) ,其中包含 DLL 中向导页、任务和验证器的配置设置。

创建自定义 UDI 任务

  1. 编写实现 ITask 接口 和以下方法的代码:

    • Init。 调用此方法可初始化任务。

    • 执行。 调用此方法以运行任务。

  2. 编写将自定义任务类工厂注册到工厂注册表的代码。

  3. 为自定义任务生成解决方案。

    注意

    确保创建的 DLL 版本与安装 MDT 的处理器平台相同。 例如,如果安装 64 位版本的 MDT,则生成 64 位版本的自定义 UDI 任务。

  4. 在 UDI 向导设计器配置文件中的 TaskLibrary 元素下创建 Task 元素,类似于以下摘录:

    <Task DLL="OSDRefreshWizard.dll" Description="Discovers supported applications for install." Type="Microsoft.OSDRefresh.AppDiscoveryTask" Name="Application Discovery">  
       <TaskItem Type="Setter" Name="Status Bitmap">  
          <Param Name="BitmapFilename"/>  
       </TaskItem>  
       <TaskItem Type="Setter" Name="Log File">  
          <Param Name="log"/>  
       </TaskItem>  
       <TaskItem Type="Setter" Name="Write Configuration File">  
          <Param Name="writecfg"/>  
       </TaskItem>  
       <TaskItem Type="Setter" Name="Read Configuration File">  
          <Param Name="readcfg"/>  
       </TaskItem>  
    </Task>  
    

    注意

    所有 Task 元素都应包含 BitmapFilename 参数。 指定任务所需的所有其他参数。 例如,在前面的摘录中, log 参数用于指定日志文件位置的参数。

  5. 将上一步中创建的 UDI 向导设计器配置文件复制到 installation_folder\Bin\Config 文件夹 (,其中 installation_folder 是安装 MDT) 的文件夹。

  6. 将自定义任务的 DLL 复制到 installation_folder\Templates\Distribution\Tools\ 平台文件夹 (其中 installation_folder 是安装 MDT 的文件夹, 平台 是 32 位版本的 x86 或 64 位版本) 的 x64

创建自定义 UDI 验证程序

UDI 验证程序 是用 C++ 编写的 DLL,用于实现 IValidator 接口。 通过创建 UDI 向导设计器配置文件 (.config 文件) 并将其放置在 installation_folder\Bin\Config 文件夹 (其中 installation_folder 是安装 MDT) 的文件夹,将 DLL 注册到 UDI 向导设计器验证程序库。

创建自定义 UDI 验证程序

  1. 编写创建 BaseValidator 类的子类并实现以下方法的代码:

    • Init (IControl *pControl,IWizardPageContainer *pContainer,IStringProperties *pProperties) 。 表单控制器调用 Init 成员来初始化验证程序。 此方法必须为 BaseValidator 类调用 Init 方法。 它通常从 UDI 向导配置文件中读取为验证程序设置的任何属性。 例如, InvalidCharactersValidator 验证程序 使用此方法检索 InvalidChars 属性的值。

    • IsValid。 窗体控制器调用此方法以查看控件是否包含有效文本。 下面是验证程序验证字段是否为空的 IsValid 方法示例:

      BOOL IsValid(LPBSTR pMessage)  
      {  
          __super::IsValid(pMessage);  
      
          _bstr_t text;  
          m_pText->GetText(text.GetAddress());  
          return (text.length() > 0);  
      }  
      
    • Init (IControl *pControl,LPCTSTR 消息) 。 表单控制器为每个击键和其他事件调用此成员,以便验证程序可以验证控件的内容,并在向导页底部 (或清除它们) 。

      通常,这些是需要重写的唯一方法。 但是,根据验证程序,可能需要替代创建的 BaseValidator 类的子类中的其他方法。 有关这些其他方法的详细信息,请参阅 BaseValidator 类。

  2. 编写向注册表工厂注册自定义任务类的代码。

  3. 为自定义任务生成解决方案。

    注意

    确保创建的 DLL 版本与安装 MDT 的处理器平台相同。 例如,如果安装 64 位版本的 MDT,则生成 64 位版本的自定义 UDI 任务。

  4. 在 UDI 向导设计器配置文件的 ValidatorLibrary 元素下创建一个 Validator 元素,类似于以下摘录:

    <Validator   
    <Validator DLL="" Description="Must follow a pre-defined pattern" Type="Microsoft.Wizard.Validation.RegEx" Name="NamedPattern">  
       <Param Description="Enter the message you want displayed when the text in this field doesn't match the pattern:" Name="Message" DisplayName="Message"/>  
       <Param Description="The name of a pre-defined regular expression pattern. Must be Username, ComputerName, or Workgroup" Name="NamedPattern" DisplayName="Named Pattern"/>  
    </Validator>  
    

    警告

    所有 验证器 元素都应包含 Message 参数。 指定验证程序所需的所有其他参数。 例如,在前面的摘录中, NamedPattern 参数用于指定预定义正则表达式模式的名称的参数。

  5. 将上一步中创建的 UDI 向导设计器配置文件复制到 installation_folder\Bin\Config 文件夹 (,其中 installation_folder 是安装 MDT) 的文件夹。

  6. 将自定义任务的 DLL 复制到 installation_folder\Templates\Distribution\Tools\ 平台文件夹 (其中 installation_folder 是安装 MDT 的文件夹, 平台 是 32 位版本的 x86 或 64 位版本) 的 x64

UDI 向导参考

向导页组件

可以使用多个预生成组件中的任何一个来生成自定义页面。

创建组件实例

UDI 向导使用类工厂为你创建对象的新实例。 这些工厂使用字符串作为工厂的键向工厂注册表注册。 例如,WmiRepository 组件由字符串“Microsoft标识。Wizard.WmiRepository“,在 IWmiRepository 头文件中作为ID_WmiRepository提供。

假设已将页面编写为 WizardPageImpl 的子类,则可以创建 WmiRepoistory 的新实例,如下所示:

PWmiRepository pWmi;  
CreateInstance(Container(), ID_WmiRepository, &pWmi);  

CreateInstance 函数是用于创建新组件实例的类型安全的模板函数。 PWmiRepository 是一个智能指针,因此它会为你处理引用计数。

可创建组件

有一组可以在注册表中注册的组件。 始终注册第一组组件,因为主 UDI 向导可执行文件提供了它。 其他两组组件在“可选”DLL 中提供。 要使这些组件可用,必须在 .config XML 文件的 DLL 节中列出 DLL。 代码不需要知道哪个可执行文件包含特定组件。

(组件名称的组件 ID 列表与 ID 相同,但未向 OSDSetupWizard ) 中 定义的工厂注册表 (注册初始ID_) 。

表 3. 组件 ID

ID 说明
ID_ACPowerTask (ITask、IWizardComponent) 一项预检任务,可确保计算机不单独使用电池运行
ID_AppDiscoveryTask (ITask,IWizardComponent) 一项用于发现计算机上已安装的软件项的专用任务
ID_BackgroundTask (IBackgroundTaskIWizardComponent) 可用于在另一个线程上运行任务
ID_CopyFilesTask (ITaskIWizardComponent) 复制一个或多个文件的任务
ID_FormController (IFormController) 你最希望不需要自己创建实例,因为页面收到自己的实例
ID_InvalidCharactersValidator (IValidator) 确保没有文本字段包含提供给验证器的列表中的字符
ID_Logger (ILogger) 你最希望不需要自己创建实例,因为页面收到指向共享实例的指针
ID_NonEmptyValidator (IValidator) 确保没有字段为空的验证程序
ID_PasswordValidator (IValidator) 确保两个文本字段没有相同内容的验证程序
ID_Regex (IRegEx) 计算正则表达式,查找匹配项
ID_RegExValidator (IValidator) 针对正则表达式或已知模式进行验证的验证程序
ID_SimpleStringProperties (IStringPropertiesISimpleStringProperties) 提供了一种简单的方法,无需使用 XML 即可将属性发送到任务
ID_ShellExecuteTask (ITaskIWizardComponent) 执行外部程序
ID_SummaryBag (ISummaryBag) 通过 Form 方法从页面间接提供
ID_TaskManager (ITaskManagerIBackgroundCallbackIWizardComponent) 管理运行一组任务和 UI
ID_WmiRepository (IWmiRepositoryIWizardComponent) 允许运行 Windows Management Instrumentation (WMI) 查询
ID_IXmlDocument (IXmlDocument) 为读取和写入 XML 文档提供外观

表 4 和表 5 中显示了定义的OSDRefreshWizard.dll、共享页和其他控件组件。

表 4. 目录控件

ID 说明
ID_Directory (IDirectory) 用于从文件系统获取目录信息的门面

表 5. 定义的SharedPages.dll

ID 说明
ID_ADHelper (IADHelper) 为 Active Directory® 域服务 (AD DS) 中的一组有限功能提供外观
ID_CpuInfo (ICpuInfo) 确定 CPU 是 32 位还是 64 位
ID_DomainJoinValidator (IDomainJoinValidator) 提供了一些用于检查是否允许一组凭据加入域的方法
ID_DriveList (IDriveListIBindableListIWizardComponent) 使用 WMI 获取计算机上的驱动器列表
ID_WiredNetworkTask (ITask) 检查是否使用硬连线 (而不是无线) 网络适配器连接到网络的任务

控制组件

通过 GetControlWrapper 模板函数与页面上的控件进行交互,该函数提供对表 6 中列出的组件类型之一的访问权限。

表 6. 组件

对话框控件类型 说明
CONTROL_CHECK_BOX (ICheckBox) 用于使用复选框控件的外观
CONTROL_COMBO_BOX (IComboBox) 组合框控件的外观
CONTROL_GENERIC (IControl) 允许使用大多数类型的控件来控制启用和可见状态
CONTROL_LIST_VIEW (IListView) 提供对列表视图控件功能的访问权限的外观
CONTROL_PROGRESS_BAR (IProgressBar) 用于处理进度栏控件位置的外观
CONTROL_RADIO_BUTTON (IRadioButton) 用于处理单选按钮控件的外观
CONTROL_STATIC_TEXT (IStaticText) 为控件的文本(如标签或文本框)提供读/写权限的外观
CONTROL_TREE_VIEW (ItreeView) 用于处理树视图控件的外观

图像列表组件

此组件是页面上 ImageList 控件的一个外观。 通过 IListViewITreeView 接口创建图像列表。

FormController 组件

向导会为你创建此组件,并将其传递到页面。 使用 WizardPageImpl 基类实现的 Form 方法从页面访问它。

InvalidCharacterValidator 组件

这是一种可以在页面上包含的验证程序类型。 ID ID_InvalidCharactersValidator (IValidator.h) 中定义,其文本值为“Microsoft。Wizard.Validation.InvalidChars。”

此验证程序在名为 InvalidChars 的 .config 文件中查找单个属性 (Setter 元素,该文件是不允许使用的字符列表) 。 它会检查文本框中的字符;如果文本包含此列表中的任何字符,则组件将报告失败。

NonEmptyValidator 组件

这是一种可以在页面上包含的验证程序类型。 ID ID_NonEmptyValidator (IValidator.h) 中定义,其文本值为“Microsoft。Wizard.Validation.NonEmpty。”

如果文本框 (或任何其他支持 IStaticText 的控件) 具有空字符串值,则此验证程序将报告失败。

PasswordValidator 组件

这是一种可以在页面上包含的验证程序类型。 ID IValidator.h) 中定义的ID_PasswordValidator (,其文本值为“Microsoft。Wizard.Validation.Password。”

此验证程序适用于两个不同的文本控件 (支持 IStaticText) 的控件,如果它们不包含相同的值,则报告失败。 换句话说,如果 “密码” 和“ 确认密码” 文本框不匹配,则失败。

由于此验证程序需要两个控件,因此它比其他验证程序需要更多设置。 设置可能如下所示:

Form()->AddToGroup(IDC_EDIT_PASSWORD, IDC_EDIT_PASSWORD2);  
PValidator pValidator;  
Form()->AddValidator(IDC_EDIT_PASSWORD, ID_PasswordValidator, pMessage, &pValidator);  
PStaticText pPassword2;  
GetControlWrapper(View(), IDC_EDIT_PASSWORD2, CONTROL_STATIC_TEXT, &pPassword2);  
pValidator->SetProperty(0, pPassword2);  

首先,将 “确认密码 ”控件定义为 “密码 ”控件的“子级”。 这样,如果表单控制器禁用 密码 控件,它还将禁用 “确认密码” 控件。 接下来,向表单添加密码验证程序。 最后,为密码验证程序提供 “确认密码 ”控件的接口。

由于要求两个控件,必须使用代码来设置此验证程序,而不是.config XML 文件。

RegExValidator 组件

这是一种可以在页面上包含的验证程序类型。 ID IValidator.h) 中定义的ID_RegExValidator (,其文本值为“Microsoft。Wizard.Validation.RegEx。”

此验证程序将文本控件的内容 (支持 IStaticText) 的文本控件与正则表达式进行比较,如果文本与正则表达式不匹配,则会失败。

或者,可以将此验证程序与预定义的命名模式一起使用。 若要使用正则表达式,XML 必须包含名为 Pattern 的 setter 属性。 如果要改用命名模式,请使用名为 NamedPattern 的 setter 设置为表 7 中的值之一。

表 7. 命名模式资源库

Pattern 说明
用户名 验证文本的格式是否为 domain\user 或user@domain
ComputerName 名称的长度必须介于 1 到 15 个字符之间,并且不能包含一组字符 (,例如 : 和 ?)
工作组 名称的长度必须介于 1 到 15 个字符之间,并且不能包含一组字符 (,例如 =、+和 ?)

FactoryRegistry 组件

此组件跟踪所有类工厂和服务。 它实现 IFactoryRegistry 接口,并通过页面的 Container 方法间接提供。 此外,注册表还会加载扩展 DLL。 加载 DLL 后,注册表会查找名为 RegisterFactories 的导出函数。 必须实现此函数,并在其中为页面、任务和验证程序注册类工厂, (以及要) 注册的任何其他类工厂。 下面是示例项目中的示例:

extern "C" __declspec(dllexport) void RegisterFactories(IFactoryRegistry *factories)  
{  
Register<LocationPageFactory>(ID_LocationPage, factories);  
}  

记录器组件

此组件可通过 WizardPageImpl) 实现的 Logger 方法 (提供给页面。 使用此方法可将条目写入日志文件。 日志文件的内容可用于诊断用户可能运行 UDI 向导的问题。

PropertyBag 组件

属性包是内存变量的容器。 可以使用 Container () -Properties> () 从页面获取它。 内存变量可用于在不同页之间传递临时数据。

TSVariableBag 和 TSRepository 组件

TSVariableBag 组件允许读取和写入任务序列变量。 默认情况下,它会将值保留在内存中,直到用户单击“ 完成 (”) 。 可以通过页面的 TSVariables 方法访问 TSVariables 包 (由 WizardPageImpl 基类) 实现。 这些组件记录任务序列变量的所有读取和写入操作。

WmiRepository 组件

此组件提供用于处理 WMI 查询的外观。 可以使用 ID_WmiRepository 调用 CreateInstance 帮助程序函数,以获取支持 IWmiRepository 接口的此组件的实例。 此组件通过 IWmiIterator 接口返回结果记录。

向导页帮助程序类

可以使用 UDI SDK 随附的内置帮助程序类创建自定义 UDI 向导页。 表 8 列出了可用于创建自定义向导页的帮助程序类。

表 8. 帮助程序类

帮助程序类 说明
ClassFactoryImpl 类 这是一个有用的基类,用于创建类工厂,然后可以在工厂注册表中注册。
接口模板类 如果要生成实现多个接口的组件,请使用此模板类。
路径帮助程序类 此类提供常见的文件/目录操作。
指针模板类 此类为 COM 组件中的生存期管理提供引用计数。 使用完接口后,释放接口非常重要。 此模板类自动处理生存期。
PUnknown 类 此类是专用于 IUnknown 接口的智能指针。 对于所有其他接口,请使用 Pointer 模板类。
StringUtil Helper 类 此类提供帮助程序方法,以便更轻松地使用字符串。
SubInterface 模板类 通过此基类,可以更轻松地实现支持自身继承自另一接口的接口的组件。
UnknownImpl 模板类 此类处理创建 COM 组件的大部分详细信息。
WizardComponent 模板类 此基类用于创建需要访问向导服务的组件,例如组件创建和日志记录。
WizardPageImpl 模板类 此基类应用作所有自定义向导页的基类

ClassFactoryImpl 类

这是一个有用的基类,用于创建类工厂,然后可以在工厂注册表中注册。

下面是示例项目中 LocationPage.h 文件中用于定义 ClassFactoryImpl 类的摘录。

#pragma once  

#include "ClassFactoryImpl.h"  

class LocationPageFactory :public ClassFactoryImpl  
{  
protected:  
    IUnknown *CreateNewInstance();  
};  

下面是示例向导页中 LocationPage.cpp 文件的摘录,用于定义页面的类工厂。

IUnknown *LocationPageFactory::CreateNewInstance()  
{  
    return static_cast<IWizardPage *>(new LocationPage);  
}  

接口模板类

如果要生成实现多个接口的组件,请使用此模板类,例如:

classLocationPage :public Interface<IFieldCallback, WizardPageImpl<IDD_LOCATION_PAGE>>  

此代码创建一个基类链,该链同时支持 IFieldCalbackWizardPageImpl 支持的接口, (恰好是 IWizardPage) 。

路径帮助程序类

此类提供常见的文件/目录操作:

static inline std::wstring GetModulePath(HINSTANCE hModule)  

它还返回.exe或.dll文件的完整路径,其中包含向此方法提供的实例句柄:

static inline std::wstring GetModuleFilename(HINSTANCE hModule)  

类返回 .exe 和 .dll 文件的完整路径和文件名,以及提供给此方法的实例句柄:

static inline std::wstring GetDirectoryName(LPCWSTR fullName)  

. . . 或仅删除文件名时的路径:

static inline std::wstring GetFileName(LPCWSTR fullName)  

给定具有文件名的路径,路径帮助程序类仅返回文件名:

static inline std::wstring Combine(LPCWSTR path, LPCWSTR name)  

最后,类返回一个新字符串,该字符串是组合路径和文件名 (或其他路径) 。

指针模板类

此类在 Pointer.h 中定义。 由于 COM 组件使用引用计数进行生存期管理,因此在完成接口后始终发布接口非常重要。 Microsoft提供了一个自动处理生存期的模板类。 例如,如果需要 XML 接口的智能指针,可以编写如下所示的内容:

Pointer<IXMLDOMNode> pNewChild  
pXmlDom->CreateNode(NODE_ELEMENT, L"MyElement", L"", &pNewChild);  

第一行定义智能指针。 第二行显示通过另一个调用检索智能指针。 如果运算符包含现有接口,则 & 始终释放该接口并返回内部指针的地址。 检索到此类指针后,当变量超出范围时, Pointer 实例会为你调用 Release 。 Microsoft建议使用智能指针,而不是手动调用 AddRefRelease

此外, Pointer 智能指针类会调用 QueryInterface 来检索其他接口。 例如,当工厂注册表创建组件的新实例时,它具有如下所示的代码:

PWizardComponent pComp = pUnknown;  
if (pComp != nullptr)  
    pComp->SetContainer(m_pContainer);  

第一行在后台调用 QueryInterface 以请求 IWizardComponent 接口。 如果组件不支持该接口,则生成的智能指针将等于 nullptr

PUnknown 类

此类是专用于 IUnknown 接口的智能指针。 对于所有其他接口,请使用 Pointer 模板类。

StringUtil Helper 类

此类在 Utilities.h 中定义,并提供有助于更轻松地处理字符串的帮助程序方法:

static inline int CompareIgnore(LPCWSTR first, LPCWSTR second)  

此方法在忽略大小写时比较两个字符串 (请参阅表 9) 。

表 9. StringUtil Helper 类

返回 说明
0 字符串匹配,忽略大小写
<0 第一 < 秒
>0 第一 > 秒

下面是一个示例:

static inline std::wstring Format(LPCWSTR input, int index, LPCWSTR value)  
static inline std::wstring Format(LPCWSTR input, int index, DWORD value)  

这些方法有点类似于 Microsoft .NET Format 方法,即参数采用 的形式{0}。 但是,它们不对输入执行任何格式设置 ,只是替换:

static inline std::wstring Printf(std::wstring format, I val)  
static inline std::wstring Printf(std::wstring format, I val1, J val2)  
static inline std::wstring Printf(std::wstring format, I val1, J val2, K val3)  
static inline std::wstring Printf(std::wstring format, I val1, J val2, K val3, L val4)  

这些是 StringCchPrintf 周围的包装器,可返回 wstring ,因此无需自己为字符串或缓冲区分配内存。

SubInterface 模板类

通过此基类,可以更轻松地实现支持自身继承自另一接口的接口的组件。 例如, ICheckBox 接口继承自 IControl。 下面是如何使用此类来定义 CheckBoxWrapper

classCheckBoxWrapper :public SubInterface<IControl, UnknownImpl<ICheckBox> >  

基接口是第一个参数,而派生接口是第二个参数。

UnknownImpl 模板类

此类在 UnknownImpl.h 中定义,处理创建 COM 组件的大部分详细信息。 下面是如何使用此基类的示例:

classDirectory :public UnknownImpl<IDirectory>  

此代码定义支持 IDirectory 接口的类。

WizardComponent 模板类

此类在 IWizardComponent.h 中定义,是用于创建需要访问向导服务的组件(例如组件创建和日志记录)的有用基类。

例如,下面是 如何定义 CopyFilesTask 组件:

classCopyFilesTask :public WizardComponent<ITask>  
{  
    ...  

此模板类的参数是要用于组件的“main”接口,对于任务,该接口为 ITask。 使用 WizardComponent 意味着组件支持在本示例中提供的接口 (ITask) 和 IWizardComponent

每当使用类工厂注册表创建新组件时,注册表会调用组件的 IWizardComponent-SetContainer> 方法,以提供组件对向导服务的访问权限。

WizardPageImpl 模板类

使用此类作为自定义页面的基类,例如:

class LocationPage :public WizardPageImpl<IDD_LOCATION_PAGE>  

参数是对话框模板的资源 ID。

向导页接口

UDI 向导使用接口访问页面上的不同控件。 在页面内,使用 GetControlWrapper 函数检索控件包装器。 下面是一个示例:

PStaticText pFormat;  
GetControlWrapper(View(), IDC_CHECK_PARTITION, CONTROL_STATIC_TEXT, &pFormat);  

此处, PStaticText 是指向 IStaticText 接口的智能指针。 当智能指针超出范围或将变量 (的地址(如 &pFormat) )传递到方法时,智能指针会自动调用 COM Release () 方法。

IADHelper 接口

__interfaceIADHelper : IUnknown  
{  
    HRESULT Init(ILogger *pLogger);  
    HRESULT ValidLogon(LPCTSTR userName, LPCTSTR password, LPCTSTR domain);  
    HRESULT HasAccess(LPCTSTR username, LPCTSTR password, LPCTSTR domain, LPCTSTR computerName, LPCTSTR accountDomain);  
};  

HRESULT Init (ILogger *pLogger)

初始化此组件,将其传递给记录器,以便它可以记录信息。

HRESULTValidLogon (LPCTSTR userName、LPCTSTR 密码、LPCTSTR 域)

此方法验证一组凭据是否有效,如表 10 所示。

表 10. HResultValidLogon

[HRESULT] 说明
S_OK 凭据有效
S_FALSE 凭据无效
E_FAIL 找不到域控制器;检查日志以了解详细信息
HRESULT HasAccess (LPCTSTR 用户名、LPCTSTR 密码、LPCTSTR 域、LPCTSTR computerName、LPCTSTR accountDomain)

此方法验证一组凭据是否对 AD DS 中的计算机对象具有读/写访问权限,如表 11 所示。

表 11. HResult HasAccess

[HRESULT] 说明
S_OK 用户有权访问
E_FAIL 用户没有访问权限。 有关其他信息,请查看日志文件。

IBackgroundTask 接口

__interface IBackgroundTask : IUnknown  
{  
    HRESULT Init(ITask *pTask, int id, IBackgroundCallback *pCallback);  
    void Start(void);  
    BOOL Running(void);  
    HRESULT Wait(DWORD waitMilliseconds);  
    HRESULT Terminate(DWORD exitCode);  
    HRESULT GetExitCode(LPDWORD pCode, HRESULT *pHresult);  
    HRESULT Close(void);  
};  
概览

“进度”页使用此类在单独的线程上运行任务。 每当要在单独的线程上执行操作时,还可以使用此类。 任务 是支持 ITask 接口的任何类。

此接口由 ID_BackgroundTask (“Microsoft 实现。Wizard.BackgroundTask“) 组件,在 IBackgroundTask.h 接口中定义。

HRESULT Init (ITask *pTask, int id, IBackgroundCallback *pCallback)

此接口初始化 组件,如表 12 所示。

表 12. HRESULT Init

参数 说明
pTask 指向类的指针,该类包含要在另一个线程上运行的代码
Id 可在回调的 Finished 方法中使用的数字,用于指示哪个任务已完成运行;如果使用相同的回调方法启动多个任务,则很有用
pCallback 实现 Finished 方法的类,每当任务完成运行时调用该方法;对 Finished 方法的调用将位于后台线程上,而不是 UI 线程上
void Start (void)

此方法在后台线程上启动任务,并返回表 13 中显示的元素。

表 13. 返回后台线程

返回 说明
E_INVALIDARG 任务已在运行,因此无法立即启动它。
E_FAIL 启动线程时出现问题。
S_OK 线程已启动。
BOOL Running ()

如果后台任务当前正在运行,则此方法返回 TRUE;如果未运行,则返回 FALSE。

HRESULT Wait (DWORD waitMilliseconds)

此方法将一直等待,直到线程停止运行或经过毫秒数。

HRESULT 终止 (DWORD exitCode)

此方法将终止正在运行的线程 (请参阅表 14 和表 15) 。 此方法返回后,此过程可能需要很短的时间才能完成。

表 14. HRESULT 终止退出代码

参数 说明
exitCode 将发送到 Finished 回调方法的退出代码, GetExitCode 方法中也提供该退出代码。

表 15. 终止代码

返回 说明
E_FAIL 对 终止的调用失败。
S_OK 终止线程的请求成功。
HRESULT GetExitCode (LPDWORD pCode,HRESULT *pHresult)

使用此方法获取在后台线程上运行任务的结果 (请参阅表 16) 。

表 16. 结果代码

参数 说明
pCode 指向将在 return 或 nullptr 上设置的 DWORD 的指针(如果不需要返回值)。 退出时,如果线程正在运行、任务的 Execute 方法返回的代码或传递给 Terminate 方法的值(如果调用该方法),则此参数设置为 STILL_ACTIVE
pHresult 指向将在 return 或 nullptr 上设置的 HRESULT 的指针(如果不需要 HRESULT 值)。
HRESULT 关闭 (void)

此方法释放后台线程。 如果线程当前正在运行,则返回 E_INVALIDARG ,否则 S_OK

ICheckBox 接口

__interface ICheckBox : IControl  
{  
    void Check(BOOL check);  
    BOOL IsButtonChecked();  
};  
void 检查 (BOOL 检查)

设置复选框的选中状态。 当 方法为 TRUE 时,复选框处于选中状态;当 方法为 FALSE 时,将清除该复选框。

BOOL IsButtonChecked ()

此方法报告复选框的当前检查状态。

IComboBox 接口

__interface IComboBox : IControl  
{  
    HRESULT Bind([in] IBindableList *pList);  
    HRESULT Select(int index);  
    int Selected(void);  
    void Add([in] LPCTSTR caption);  
    HRESULT GetText([out, retval] LPBSTR pText);  
    void Clear();  
};  
概览

此接口由 CheckBoxWrapper 组件实现。 使用类型为 CONTROL_COMBO_BOXGetControlWrapper 帮助程序函数检索此组件的实例。

HRESULT 绑定 ([in] IBindableList *pList)

如果有实现 IBindableList 接口的数据源,请使用此方法。 列表框使用此列表中的标题初始化内容。

HRESULT select (int index)

在索引处选择组合框中的项。

int Selected (void)

此方法返回所选项的索引;如果未选择任何内容,则返回 -1

void Add ([in] LPCTSTR caption)

手动将项添加到组合框。

HRESULT GetText ([out, retval] LPBSTR pText)

检索组合框中当前选定项的字符串。

void Clear ()

从组合框中删除所有项。

IControl 接口

__interface IControl : IUnknown  
{  
    HRESULT SetEnable(BOOL enable);  
    BOOL IsEnabled(void);  
    HRESULT SetVisible(BOOL visible);  
};  
概览

此接口由 ControlWrapper 组件实现。 使用类型为 CONTROL_GENERICGetControlWrapper 帮助程序函数检索此组件的实例。

HRESULT SetEnable (BOOL 启用)

启用或禁用控件。

BOOL IsEnabled (void)

如果控件已启用,则返回 TRUE;如果未启用,则返回 FALSE。

HRESULT SetVisible (BOOL 可见)

显示或隐藏控件。

ICpuInfo 接口

__interface ICpuInfo : IUnknown  
{  
    BOOL Is64Bit(void);  
};  
概览

可以通过创建新的 ID_CpuInfo 组件来获取此接口。 单一方法报告 CPU 是 32 位还是 64 位。 请注意,如果在 64 位计算机上具有 32 位操作系统,此方法将返回 TRUE,因为它只报告 CPU (的宽度,而不报告操作系统) 。

IDirectory 接口
__interface IDirectory : IUnknown  
{  
    BOOL FileExists(LPCWSTR name);  
    BOOL FindFirst([in] LPCWSTR name);  
    HRESULT FoundName([out, retval] LPBSTR name);  
    DWORD FoundAttributes(void);  
    BOOL FindNext(void);  
    void FinishFind(void);  
};  
概览

使用 ID_Directory 创建的目录组件为在文件系统中使用目录提供了一个外观。

BOOL FileExists (LPCWSTR 名称)

如果存在具有你提供的名称的文件,则此方法返回 TRUE。

BOOL FindFirst ([in] LPCWSTR 名称)

此方法查找你提供的名称的第一个匹配项。 它支持通配符并返回文件和目录名称。 如果找到匹配项,则方法返回 TRUE,否则返回 FALSE。

HRESULT FoundName ([out, retval] LPBSTR 名称)

此方法检索通过调用 FindFirstFindNext 找到的文件的名称。

DWORD FoundAttributes (void)

此方法返回最新找到的文件或目录的 属性。 可以使用如下所示的代码来测试它是否为目录:

pDirectory->FoundAttributes() & FILE_ATTRIBUTE_DIRECTORY  
BOOL FindNext (void)

查找下一个。 如果找到另一个匹配项,则此方法返回 TRUE;否则返回 FALSE。

void FinishFind (void)

此方法释放用于“查找”操作的资源。

IDomainJoinValidator 接口

__interface IDomainJoinValidator : IUnknown  
{  
    HRESULT Init(ILogger *pLogger, IWizardPageContainer *pContainer, IStaticText *pUsername, IStaticText *pPassword, IStaticText *pComputerName);  
    HRESULT IsUsernameValid(LPCWSTR domainName);  
    BOOL CanModifyComputerAdEntry(LPCWSTR domainName);  
};  
概览

使用 CreateInstance 模板函数的 ID_DomainJoinValidator 值获取此接口的实例。

HRESULT Init (ILogger *pLogger, IWizardPageContainer *pContainer, IStaticText *pUsername, IStaticText *pPassword, IStaticText *pComputerName)

初始化实例,如表 17 所示。

表 17. HRESULT Init - 实例初始化

参数 说明
pLogger 记录器实例,它可通过页面的 Logger 方法提供给页面
pContainer 传递页面的 Container 方法的结果
pUsername 包含要验证的用户名的文本框
pPassword 包含要验证的密码的文本框
PComputerName 包含最终将加入域的计算机名称的文本框
HRESULT IsUsernameValid (LPCWSTR domainName)

此方法使用 IADHelper-ValidLogon> 方法完成工作。 有关详细信息,请参阅该方法。

BOOL CanModifyComputerAdEntry (LPCWSTR domainName)

验证用户是否有权修改计算机条目。 大部分工作由 IADHelper-HasAccess> 完成。 如果此方法返回 FALSE,请检查日志文件以了解详细信息。

IDriveList 接口

__interface IDriveList : IUnknown  
{  
    HRESULT Init(IWmiRepository *pWmi);  
    HRESULT SetWhereClause(LPCTSTR whereClause);  
    HRESULT SetMinimumDriveSize(__int64 size);  
    HRESULT Update(void);  
    HRESULT AddProperty(ENUM_DISK_QUERY_SECTION section, LPCTSTR propName, LPCTSTR propNameReturned);  

    size_t Count(void);  
    HRESULT GetProperty(size_t index, LPCTSTR propName,  LPVARIANT value);  
    HRESULT GetCaption(size_t index,  LPBSTR pCaption);  
}  
HRESULT Init (IWmiRepository *pWmi)

在调用任何其他组件之前调用此方法。 在调用此方法之前,需要创建新的 WmiRepository

HRESULT SetWhereClause (LPCTSTR whereClause)

此方法允许添加将在查询中显示为“where”子句的文本。 例如,以下行仅返回 USB 驱动器:

pDrives->SetWhereClause(L"WHERE InterfaceType='USB'");  
HRESULT SetMinimumDriveSize (__int64 大小)

为将从查询返回的驱动器设置最小驱动器大小(以字节为单位)。

HRESULT 更新 (void)

执行查询。 调用此方法后可用的驱动器列表按驱动器号排序。

HRESULT AddProperty (ENUM_DISK_QUERY_SECTION 节,LPCTSTR propName,LPCTSTR propNameReturned)

此方法添加要在查询结果中提供的其他属性的名称。 在调用 Update 之前调用此方法。 表 18 显示了三个有用的属性。

表 18. HRESULT AddProperty:有用的属性

Section 属性 说明
DISKQUERY_LOGICALDISK Size 以字符串表示的大小(以字节为单位)
DISKQUERY_DISKPARTITION DiskIndex 以整数表示的磁盘编号,从 0 开始
DISKQUERY_LOGICALDISK VolumeName 卷标签
size_t计数 (void)

查询返回的记录数。 在调用此方法之前,请调用 Update

HRESULT GetProperty (size_t index、LPCTSTR propName、LPVARIANT 值)

此方法从查询结果中检索属性的值,如表 19 所示。

表 19. HRESULT GetProperty

参数 说明
"索引" 结果记录的从零开始的索引
propName 属性的名称,例如“Size”
返回时,此参数包含 属性的变体值
HRESULT GetCaption (size_t 索引,LPBSTR pCaption)

此方法检索与 Caption 属性相同的记录的 标题

IImageList 接口

__interface IImageList  
{  
    HRESULT CreateImageList(int width, int height, UINT flags);  
    HImageList GetImageList(void);  
    int AddImage(HInstance hInstance, int resourceId);  
};  
概览

此接口由 ImageList 组件实现。 从 IListView 接口检索此组件的实例。

HRESULT CreateImageList (int width、int height、UINT 标志)

创建此组件管理的新映像列表。 仅调用此方法一次。

HImageList GetImageList (void)

如果需要对映像列表执行其他操作,此方法返回图像列表的句柄。

int AddImage (HInstance hInstance, int resourceId)

从资源向映像列表添加新图像,如表 20 所示。

表 20. HRESULT IImageList 接口

参数 说明
hInstance 包含位图资源的模块的实例句柄
resourceId 要加载到映像列表中的资源的 ID

IListView 接口

__interface IListView : IControl  
{  
    int AddItem([in] LPCTSTR text);  
    int AddColumn(int width, [in] LPCTSTR text);  
    HRESULT SetSubItem(int index, int column, [in] LPCTSTR text);  
    int GetWidth(void);  
    void SetExtendedStyle(DWORD style);  
    int GetSelectedItem(void);  
    HRESULT SelectItem(int index);  
    BOOL IsItemChecked(int index);  
    int GetItemCount(void);  
    HRESULT CreateImageList(int width, int height, UINT flags);  
    int AddImage(HINSTANCE hInstance, int resourceId);  
    HRESULT SetImage(int index, int imageIndex);  
    HRESULT Clear(void);  
};  
概览

此接口由 ControlWrapper 组件实现。 使用类型为 CONTROL_LIST_VIEWGetControlWrapper 帮助程序函数检索此组件的实例。

int AddItem ([in] LPCTSTR 文本)

向列表框添加新行。 方法返回刚刚添加的项的索引。

int AddColumn (int width, [in] LPCTSTR 文本)

向列表视图添加新列。

HRESULT SetSubItem (int index, int column, [in] LPCTSTR 文本)

在列表框的第一列以外的列中设置文本,如表 21 所示。

表 21. HRESULT SetSubItem

参数 说明
index 要修改的列表项的索引
要更新的列的索引;使用 AddItem 设置第一列,使用此方法设置第二列和以下列
text 要显示在列中的字符串
int GetWidth (void)

此方法返回整个文本框的宽度。

void SetExtendedStyle (DWORD 样式)

此方法允许对列表框设置扩展样式,例如:

m_pList->SetExtendedStyle(LVS_EX_FULLROWSELECT);  
int GetSelectedItem (void)

此方法返回当前所选列表视图项的索引。

HRESULT SelectItem (int index)

将列表中的选定项设置为此索引。

BOOL IsItemChecked (int 索引)

如果选择了列表中的项,则此方法返回 TRUE。 此方法要求调用 SetExtendedStyle 来设置复选框样式。

int GetItemCount (void)

此方法返回列表视图中的项数。

HRESULT CreateImageList (int width、int height、UINT 标志)

创建新的映像列表,并将其附加到列表视图。

int AddImage (HINSTANCE hInstance, int resourceId)

将图像添加到列表视图的图像列表。 首先需要调用 CreateImageList

HRESULT SetImage (int index,int imageIndex)

设置将在左侧为特定列表视图项显示的图像。

HRESULT 清除 (void)

从列表视图中删除所有项。

IProgressBar 接口

__interface IProgressBar : IControl  
{  
    HRESULT SetPercentage(int position);  
    int GetPercentage(void);  
};  
概览

此接口由 ProgressBarWrapper 组件实现。 使用类型为 CONTROL_PROGRESS_BARGetControlWrapper 帮助程序函数检索此组件的实例。

HRESULT SetPercentage (int 位置)

使用介于 0 和 100 之间的数字设置进度栏的位置。 默认情况下,新的 Win32® 进度栏的最大范围为 100。

int GetPercentage (void)

此方法返回进度栏的当前位置。

IRadioButton 接口

__interface IRadioButton : IControl  
{  
public:  
    void SetGroup(int firstId, int lastId);  
    void CheckRadio(int id);  
    BOOL IsButtonChecked(int id);  
    void EnableRadio(int id, BOOL enable);  
};  
概览

此接口由 RadioButtonWrapper 组件实现。 使用类型为 CONTROL_RADIO_BUTTONGetControlWrapper 帮助程序函数检索此组件的实例。

void SetGroup (int firstId, int lastId)

为包装器提供应被视为组的单选按钮范围。 在调用 CheckRadio 之前调用此方法。

void CheckRadio (int id)

将特定单选按钮设置为所选单选按钮组中的单个按钮。 在调用此方法之前调用 SetGroup

BOOL IsButtonChecked (int id)

如果当前选择了单选按钮,则此方法返回 TRUE,否则返回 FALSE。

void EnableRadio (int id,BOOL enable)

此方法启用或禁用单选按钮。

IStaticText 接口

__interface IStaticText : IControl  
{  
    HRESULT SetText([in] LPCTSTR pText);  
    HRESULT GetText([out, retval] LPBSTR pText);  
};  
概览

此接口由 StaticTextWrapper 组件实现。 使用类型为 CONTROL_STATIC_TEXTGetControlWrapper 帮助程序函数检索此组件的实例。

HRESULT SetText ([in] LPCTSTR pText)

设置控件的文本。

HRESULT GetText ([out, retval] LPBSTR pText)

此方法返回控件的文本的当前值。

ITask 接口

__interface IControl : IUnknown  
{  
    HRESULT Init(IStringProperties *pProperties, ISettingsProperties *pTaskSettings);  
    HRESULT Execute(LPDWORD pReturnCode);  
};  

如果希望组件在预检页中作为任务可用,或者想要使用 BackgroundTask 组件在后台线程上执行工作,则实现此接口。

下面是实现 ITask 接口的 组件:

  • ID_ShellExecuteTask,L“Microsoft。Wizard.ShellExecuteTask”

  • ID_CopyFilesTask,L“Microsoft。Wizard.CopyFilesTask”

  • ID_ACPowerTask,L“Microsoft。OSDRefresh.ACPowerTask”

  • ID_WiredNetworkTask,L“Microsoft。SharedPages.WiredNetworkTask”

初始
HRESULT Init(IStringProperties *pProperties, ISettingsProperties *pTaskSettings)  

如果要为预检页编写任务,请调用此方法来初始化任务。 .config 文件包含的 XML 可能如下所示:

<Task DisplayName="Check Windows Scripting Host" Type="Microsoft.Wizard.ShellExecuteTask">  
  <Setter Property="filename">%windir%\system32\cscript.exe</Setter>  
  <Setter Property="parameters">Preflight\OSDCheckWSH.vbs</Setter>  
  <Setter Property="BitmapFilename">images\WinScriptHost.bmp</Setter>  
  <ExitCodes>  
    <ExitCode State="Success" Type="0" Value="0" Text="" />  
    <ExitCode State="Error" Type="-1" Value="*" Text="Windows Scripting Host not installed." />  
  </ExitCodes>  
</Task>  

pProperties 参数提供对三个 setter 值的访问权限,而 pTaskSettings 参数提供对 Task 元素和子元素的访问权限。 大多数任务只需从 pProperties 参数读取数据。

执行
HRESULT Execute(LPDWORD pReturnCode)  

在此处编写执行任务的代码。 如果没有错误,此方法应返回 S_OK ;如果在任务运行时发生错误,此方法可以返回另一个 HRESULT 。 如果使用预页,则此方法返回S_OK以外的值与 ExitCodes> 节中的 <Error> 元素匹配<。

pReturnCode 参数必须更新为报告任务状态的数字。 这些值与 ExitCode> 元素的 pre 一页<匹配。

ITreeView 接口

__interface ITreeView : IControl  
{  
    void EnableCheckboxes(void);  
    HRESULT CreateImageList(int width, int height, UINT flags);  
    int AddImage(HINSTANCE hInstance, int resourceId);  

    HTREEITEM AddItem(LPCTSTR text, HTREEITEM hParent = NULL);  
    void SetImage(HTREEITEM item, int image, int expandImage);  

    void Clear(void);  
    BOOL SetFirstVisible(HTREEITEM item);  
    BOOL SelectItem(HTREEITEM item);  
    void CheckItem(HTREEITEM item, UINT checkState);  
    HTREEITEM SelectedItem(void);  
    int SetItemHeight(SHORT height);  
    HRESULT EnableItem(HTREEITEM item, BOOL enable);  
    void Expand(HTREEITEM hItem, BOOL expand);  

    HTREEITEM GetChild(HTREEITEM hParent);  
    HTREEITEM GetParent(HTREEITEM hNode);  
    HTREEITEM GetNextItem(HTREEITEM hPrevious);  

    UINT IsChecked(HTREEITEM item);  
    BOOL IsEnabled(HTREEITEM item);  

    INT_PTR CommonControlEvent(WORD controlId, void* pInfo, BOOL *pCancel);  
    HRESULT SetEventHandler(ITreeViewEvent *pEventHandler);  

    void SetSelectedBackColor(COLORREF color);  
};  
概览

此接口由 TreeViewWrapper 组件实现。 使用类型为 CONTROL_TREE_VIEWGetControlWrapper 帮助程序函数检索此组件的实例。

void EnableCheckboxes (void)

此方法通过设置 TVS_CHECKBOXES 样式打开树视图控件中的复选框。

HRESULT CreateImageList (int width、int height、UINT 标志)

向树视图控件添加新的图像列表。 flags 参数在调用 ImageList_Create Win32 函数中传递。

int AddImage (HINSTANCE hInstance, int resourceId)

使用实例句柄 hInstance 的模块中的 resource (resourceId) 将映像添加到映像列表。

HTREEITEM AddItem (LPCTSTR 文本,HTREEITEM hParent = NULL)

将节点添加到树视图中。 如果 hParent 为 NULL,则会在顶层添加新节点。 否则,请提供要在其中添加新项的父项的句柄。 此方法返回新项的句柄。

void SetImage (HTREEITEM 项,int image,int expandImage)

设置要用于树视图项的图像。 可以设置普通映像和扩展映像。

void 清除 (void)

从树视图中删除所有项。

BOOL SetFirstVisible (HTREEITEM 项)

确保树视图项可见。 如果需要,树视图将滚动以使此项可见。

BOOL SelectItem (HTREEITEM 项)

将当前选定的项设置为你提供的项。 可以在此之后调用 SetFirstVisible ,以确保新选择的项可见。

void CheckItem (HTREEITEM 项,UINT checkState)

方法基本上设置将在树视图中为复选框显示的图像。 这些图像位于树视图管理的单独 ImageList 控件中。 默认情况下,此图像列表包含三个图像,如表 22 所示。

表 22.void CheckItem 映像列表默认值

checkState 说明
0 空白
1 清除
2 已选中
HTREEITEM SelectedItem (void)

此方法返回当前所选树视图项的句柄。

int SetItemHeight (SHORT height)

此方法设置树视图控件中所有项的高度(以像素为单位)。 它返回以前的高度(以像素为单位)。

HRESULT EnableItem (HTREEITEM 项,BOOL enable)

此方法启用或禁用树中的单个项。 禁用包含子项的项目不会禁用子项。

void 展开 (HTREEITEM hItem,BOOL 展开)

此方法可展开或折叠树中的节点。

HTREEITEM GetChild (HTREEITEM hParent)

此方法返回树视图项的第一个子级,如果没有子项,则返回 NULL。

HTREEITEM GetParent (HTREEITEM hNode)

此方法返回树视图中节点的父级句柄;如果节点位于顶层,则返回 NULL。

HTREEITEM GetNextItem (HTREEITEM hPrevious)

可以使用 GetChild 返回的句柄来调用此方法,以循环访问节点的所有子级。 此方法返回树中共享同一父级的下一个同级。

UINT IsChecked (HTREEITEM 项)

如果未选择树视图节点,则此方法返回 0 ;如果是,则返回 1

BOOL IsEnabled (HTREEITEM 项)

如果启用树视图节点,此方法返回 TRUE,否则返回 FALSE。

INT_PTR CommonControlEvent (WORD controlId,void* pInfo,BOOL *pCancel)

此方法仅供内部使用。

HRESULT SetEventHandler (ITreeViewEvent *pEventHandler)

如果要在所选项更改或用户更改树视图项的检查状态时收到通知,请调用此方法。 必须在组件中实现 ITreeViewEvent 才能接收这些回调。

void SetSelectedBackColor (COLORREF 颜色)

设置用于所选项的背景色。

IWmiIteration 接口

__interface IWmiIterator : IUnknown  
{  
    HRESULT Next(void);  
    HRESULT GetProperty(LPCTSTR propertyName, [out] LPVARIANT pValue);  
};  
概览

在使用 WMI 调用时,通常使用此接口和 IWmiRepositoryIWmiIteration 接口允许循环访问查询返回的值。

HRESULT 下一个 (void)

移动到查询结果中的下一项,如表 23 所示。

表 23. HRESULT 下一个 (void) 查询返回

HRRESULT 说明
S_OK 移动到下一个结果;可以使用 GetProperty 检索该结果的属性。
S_FALSE 列表中没有其他项。
E_NOT_SET 没有查询结果
HRESULT GetProperty (LPCTSTR propertyName, [out] LPVARIANT pValue)

此方法从当前结果记录中检索属性的值,如表 24 和表 25 所示。

表 24. HRESULT GetProperty

参数 说明
PropertyName 要检索的属性的名称
pValue 指向返回时包含属性值的 VARIANT 结构

表 25. HRESULT GetProperty 结果

[HRESULT] 说明
S_OK 已检索属性值。
WBEM_E_NOT_FOUND 没有名称为 的属性。
E_NOT_VALID_STATE 没有当前记录。

注意

GetProperty 方法可以返回除表 25 中列出的代码以外的其他 WMI 错误代码。 列出的值是返回的常见结果。

IWmiRepository 接口

__interface IWmiRepository : IUnknown  
{  
    HRESULT SetNamespace(LPCWSTR namespaceName);  
    HRESULT ExecQuery(LPCWSTR query, [out] IWmiIterator **ppIterator);  
};  
概览

此接口由 WmiRepository 组件 (ID_WmiRepository) 实现。

HRESULT SetNamespace (LPCWSTR namespaceName)

此方法设置将用于查询的 WMI 命名空间。 在调用 ExecQuery 之前调用此方法。 如果不调用此方法,命名空间将为 root\cimv2。 此方法始终返回 S_OK

HRESULT ExecQuery (LPCWSTR 查询, [out] IWmiIterator **ppIterator)

通过调用 SetNamespace 针对 WMI 命名空间集执行查询,如表 26 和表 27 所示。

表 26. HRESULT ExecQuery

参数 说明
Query 要执行的 WMI 查询的字符串
ppIterator 将指针传递给接口指针,返回时将使用接口填充该指针,以便访问查询结果

表 27. HRESULT 查询结果

[HRESULT] 说明
S_OK 查询成功
其他 如果查询未成功,则返回 WMI HRESULT

IFormController 接口

__interface IFormController : IUnknown  
{  
    Init(IWizardPageView *pView, IWizardPageContainer *pContainer);  
    SetPageInfo(ISettingsProperties *pPageInfo);  

    Validate(void);  

    AddToGroup(int groupControlId, int controlId);  
    UpdateCheckGroup(int groupControlId);  
    AddValidator(int controlId, IValidator *pValidator, IControl *pCOntrol = 0);  

    AddValidator(int controlId, LPCWSTR validatorId, LPCWSTR message, IValidator **ppValidator = nullptr);  
    DisableValidation(int controlId, BOOL disable);  

    AddField(LPCWSTR fieldName, int controlId, BOOL suppressLog, DialogControlTypes type);  
    AddRadioGroup(LPCWSTR groupName, int radioControlId);  
    EnableRadioGroup(LPCWSTR groupName, BOOL enable);  
    InitFields(IFieldCallback *pFieldCallback = nullptr);  
    SaveFields(IFieldCallback *pFieldCallback = nullptr);  
    BOOL IsFieldDisabled(int controlId);  

    InitSection(LPCWSTR key, LPCWSTR sectionCaption);  
    AddSummaryItem(LPCWSTR first, LPCWSTR second);  
    SuppressLogValue(LPCWSTR tsVariableName);  
    SaveText(int controlId, LPCWSTR tsVariableName, LPCWSTR summaryCaption);  
    LoadText(int controlId, LPCWSTR tsVariableName);  

    void ControlEvent(WORD eventId, WORD controlId);  
    BOOL IsValid(void);  
 };  
概览

UDI 向导中的每个页面都有其自己的表单控制器,用于实现此接口。 使用此控制器将 .config XML 文件中的字段数据连接到页面上的控件。 然后,表单控制器会为你处理许多详细信息。

设置窗体

通常,在页面的 OnWindowCreated 方法中设置表单控制器。 这样做通常涉及调用表 28 中所示的方法。

表 28. OnWindowCreated 方法

方法 说明
初始 初始化表单控制器
AddField 提供.config XML 文件中作为字符串名称的字段与页面对话框中作为 ID 的控件之间的连接
AddRadioGroup 用于将单选按钮连接到对话框中的组和控件
AddToGroup 允许你启用或禁用其父级或基于哪个单选按钮的“子”控件
InitFields 调用所有 Add 方法以设置窗体后调用
Validate 执行初始验证
处理表单事件

将以下调用添加到 OnControlEvent 方法:

Form()->ControlEvent(eventId, controlId);  

此调用将事件传递到窗体控制器,以便它可以处理与表单相关的事件。

保存表单数据

OnNextClicked 方法中,调用表 29 中显示的表单方法。

表 29. OnNextClicked 方法

方法 说明
InitSection 提供将在此页面的 “摘要 ”页上显示的分区的名称
SaveFields 将字段值保存到任务序列变量和 “摘要 ”页
初始
HRESULT Init(IWizardPageView *pView, IWizardPageContainer *pContainer)  

通常,在页面的 OnWindowCreated 方法的开头附近调用此方法。 命令应如下所示:

Form()->Init(View(), Container());  
SetPageInfo
HRESULT SetPageInfo(ISettingsProperties *pPageInfo)  

此方法在内部调用,不应自行调用。 它将页面的 XML 提供给表单控制器。

验证
HRESULT Validate(void)  

此方法执行附加到控件的所有验证程序。 如果验证程序未通过,表单控制器将显示警告消息并禁用“ 下一步 ”按钮,然后停止处理验证程序。 通常,只需在 OnWindowCreated 方法末尾调用此方法;它始终返回 S_OK

AddToGroup
AddToGroup(int groupControlId, int controlId)  

此方法将控件添加为复选框或单选按钮的“子”,如表 30 所示。 未选择父控件时,将禁用所有此类子控件。 方法始终返回 S_OK

表 30. AddToGroup

参数 说明
groupControlId 将控制子控件的启用状态的复选框或单选按钮的 ID
受控 要添加为子级的控件的 ID
UpdateCheckGroup
HRESULT UpdateCheckGroup(int groupControlId)  

此方法根据父控件的状态更新组的子控件的启用或禁用状态。 通常,不需要自己调用此方法,因为表单控制器会为你调用此方法。

AddValidator
HRESULT AddValidator(int controlId, IValidator *pValidator, IControl *pControl = 0)  

仅当想要在代码中创建而不是使用 XML 创建的验证程序时,才调用此方法。 此方法始终返回 S_OK

AddValidator
HRESULT AddValidator(int controlId, LPCWSTR validatorId, LPCWSTR message, IValidator **ppValidator = nullptr)  

仅当想要在代码中创建而不是使用 XML 创建的验证程序时,才调用此方法。

DisableValidation
HRESULT DisableValidation(int controlId, BOOL disable)  

调用此方法可显式禁用控件的验证程序或还原正常验证,如表 31 所示。 例如,当对表单验证未涵盖的控件启用/禁用规则,并且需要禁用控件的验证时,此方法非常有用。 换句话说,通常不会调用此方法。 此方法始终返回 S_OK

表 31. HRESULT DisableValidation

参数 说明
controlId 要为其启用或禁用验证的控件
Disable 设置为 TRUE 可禁用验证,将 设置为 FALSE 以还原正常验证
AddField
HRESULT AddField(LPCWSTR fieldName, int controlId, BOOL suppressLog, DialogControlTypes type)  

在 .config XML 文件的 Field 元素中的名称与页面对话框中的控件 ID 之间添加控件映射,如表 32 所示。 必须在调用 InitFields 之前调用此方法,因为 InitFields 使用此信息。 此方法始终返回 S_OK

表 32. HRESULT AddField

参数 说明
Fieldname 显示在页面的 XML 中的字段的名称
controlId 页面对话框模板中控件的 ID
suppressLog 如果不希望将此字段中的值写入日志文件,请将 设置为 TRUE;密码或 PIN 字段的此参数始终设置为 TRUE
类型 控件的类型,属于以下项之一:

- CONTROL_STATIC_TEXT
- CONTROL_COMBO_BOX
- CONTROL_LIST_VIEW
- CONTROL_PROGRESS_BAR
- CONTROL_GENERIC
- CONTROL_RADIO_BUTTON
- CONTROL_CHECK_BOX
- CONTROL_TREE_VIEW
AddRadioGroup
HRESULT AddRadioGroup(LPCWSTR groupName, int radioControlId)  

此方法将控件添加到命名的单选按钮组,如表 33 所示。 必须在 InitFields 方法之前调用此方法,因为该方法使用 RadioGroup 元素上的属性来控制组中所有单选按钮控件的设置。 例如,可以锁定单选组,以便禁用所有单选按钮,但仅根据选择的单选按钮启用或禁用子控件。 此方法始终返回 S_OK

表 33. HRESULT AddRadioGroup

参数 说明
groupName 定义此页上的一组单选按钮的字符串
radioControlId 要添加到此组的单个单选按钮的 ID
EnableRadioGroup
HRESULT EnableRadioGroup(LPCWSTR groupName, BOOL enable)  

此方法允许启用或禁用整个单选按钮组。 禁用单选组会禁用组中的所有单选按钮控件,以及随 AddToGroup 一起添加的单选按钮的任何子级。 请参阅表 34 和表 35。

表 34. EnableRadioGroup

参数 说明
groupName 已通过调用 AddRadioGroup 定义的单选按钮组的名称
Enable 设置为 TRUE 以启用单选按钮组,将 FALSE 设置为禁用组

表 35. HRESULT EnableRadioGroup

[HRESULT] 说明
S_OK 组启用或禁用
E_INVALIDARG 没有具有你提供的名称的单选按钮组
InitFields
HRESULT InitFields(IFieldCallback *pFieldCallback = nullptr)  

在调用此方法之前,请为 XML 可以控制的每个字段调用 AddField 。 此方法始终返回 S_OK

pFieldCallback 参数是可选的。 如果提供,表单控制器会为非CONTROL_STATIC_TEXTCONTROL_CHECK_BOX的控件调用 SetFieldDefault。 此行为允许你从 XML 中检索默认值,并在控件中自行设置该值。

SaveFields
HRESULT SaveFields(IFieldCallback *pFieldCallback = nullptr)  

此方法将字段值保存到任务序列变量以及将在“ 摘要 ”页上显示的摘要数据中。 在 pFieldCallback 中提供指针可以处理不支持 CONTROL_STATIC_TEXT的控件的保存值。

IsFieldDisabled
BOOL IsFieldDisabled(int controlId)  

使用此方法,可以确定是否在 XML 中禁用了字段。

InitSection
HRESULT InitSection(LPCWSTR key, LPCWSTR sectionCaption)  

此方法初始化将在“ 摘要 ”页上显示的摘要数据,如表 36 所示。 在调用 SaveFields 之前,请在 OnNextClicked 方法中调用此方法。 此方法始终返回 S_OK

表 36. HRESULT InitSection

参数 说明
Key 此参数对页面应是唯一的。 它用于确保每个页面都有自己的摘要信息。
sectionCaption 将在此页的摘要信息“ 摘要 ”页上显示的标头。 通常,使用 DisplayName () 作为此参数的值。
AddSummaryItem
HRESULT AddSummaryItem(LPCWSTR first, LPCWSTR second)  

此方法允许将摘要项添加到“ 摘要 ”页的上方和超过使用 XML 设置的项。 请参阅表 37。

表 37. HRESULT AddSummaryItem

参数 说明
第一 摘要项的标题,显示在左侧
Second 将在右侧显示的值
SuppressLogValue
HRESULT SuppressLogValue(LPCWSTR tsVariableName)  

为不希望将值写入日志文件的任务序列变量调用此方法。 为存储密码、PIN 或用户可能输入的其他敏感值的任务序列变量调用此方法。

SaveText
HRESULT SaveText(int controlId, LPCWSTR tsVariableName, LPCWSTR summaryCaption)  

此方法将文本控件的值保存到任务序列变量和摘要部分。 通常,不需要自己调用此方法,因为表单控制器对所有字段执行此操作。 请参阅表 38。

表 38. HRESULT SaveText

参数 说明
controlId 文本框的 ID,其中包含要保存的值 (或任何其他可返回文本的控件)
tsVariableName 要修改的任务序列变量的名称
summaryCaption 此值的 “摘要 ”页上的标题
LoadText
HRESULT LoadText(int controlId, LPCWSTR tsVariableName)  

此方法读取任务序列变量的值,并将文本框设置为此值。

ControlEvent
void ControlEvent(WORD eventId, WORD controlId)  

OnControlEvent 方法上调用此方法,以确保表单控制器可以处理控制事件,它需要执行这些操作才能正常运行。 传递给此方法的值与传递给 OnControlEvent 方法的值相同。

IsValid
BOOL IsValid(void)  

此方法返回窗体的最新验证状态。 如果任何控件验证程序报告了错误,则此方法返回 FALSE。 换句话说,仅当页面上的所有控件都有效时,它才返回 TRUE。

IValidator 接口

__interface IValidator : IUnknown  
{  
    HRESULT Init(IControl *pControl, LPCTSTR message);  
    HRESULT Init(IControl *pControl, IWizardPageContainer *pContainer, IStringProperties *pProperties);  
    BOOL, IsValid(LPBSTR pMessage);  
    HRESULT SetProperty(int propertyId, LPVARIANT pValue);  
    HRESULT SetProperty(int propertyId, IUnknown *pUnknown);  
    HRESULT SetProperty)(int propertyId, LPCTSTR pValue);  
};  
概览

验证程序 是可以验证页面上的单个控件的组件。 实现验证程序的最简单方法是使其成为 BaseValidator 类的子类,该类在 BaseValidator.h 头文件中定义。

HRESULT Init (IControl *pControl,LPCTSTR 消息)

如果在代码中创建验证程序,则可以调用此方法来初始化验证程序。 请参阅表 39。

表 39. HRESULT Init

参数 说明
pControl 验证程序必须验证的控件
邮件 控件无效时在页面上显示的消息
HRESULT Init (IControl *pControl, IWizardPageContainer *pContainer, IStringProperties *pProperties)

表单控制器调用此方法以初始化它基于页面的 XML 创建的验证程序。 请参阅表 40。

表 40. HRESULT Init 方法

参数 说明
pControl 验证程序必须验证的控件
pContainer 如果验证程序需要访问记录器或需要创建其他组件
pProperties 提供对验证程序 (setter 元素) 属性的访问权限
BOOL、IsValid (LPBSTR pMessage)

如果控件有效,则此方法返回 TRUE;如果控件无效,则返回 FALSE。 返回时,应使用包含控件无效时要显示的消息的新 BSTR 填充 pMessage

HRESULT SetProperty (int propertyId, LPVARIANT pValue)

如果需要 XML 中未提供的额外值,则可以实现此方法。

HRESULT SetProperty (int propertyId, IUnknown *pUnknown)

如果需要 XML 中未提供的额外值,则可以实现此方法。

HRESULT SetProperty) (int propertyId, LPCTSTR pValue)

如果需要 XML 中未提供的额外值,则可以实现此方法。

IRegEx 接口

__interface IRegEx : IUnknown  
{  
    BOOL MatchesRegex(LPCTSTR input, LPCTSTR regex);  
    HRESULT GetMatch(size_t index, LPBSTR pValue);  
};  

此方法由 ID_Regex 组件 (IRegex.h) 实现,并支持正则表达式处理。

BOOL 匹配正则表达式 (LPCTSTR 输入,LPCTSTR 正则表达式)

此方法针对输入文本运行正则表达式。 它使用 C++ 标准库的 regex_match 函数来执行实际工作。 如果存在匹配项,则方法返回 TRUE,否则返回 FALSE。

HRESULT GetMatch (size_t index,LPBSTR pValue)

此方法允许从最近的 MatchesRegex 调用中检索匹配项。 请注意,此方法中没有错误处理,它返回 S_OK 或引发异常。

ISummaryInfo 接口

__interface ISummaryInfo : IUnknown  
{  
    size_t Count(void);  
    HRESULT Clear(void);  
    HRESULT AddInfo(LPCTSTR pFirst, LPCTSTR pSecond);  
    HRESULT GetInfo(size_t index, LPBSTR pFirst, LPBSTR pSecond);  
    HRESULT GetCaption(LPBSTR pCaption);  
    HRESULT SetCaption(LPCTSTR caption);  
};  

不应直接使用此接口。 请改用 IFormController

ISummaryBag

__interface ISummaryBag : IUnknown  
{  
    size_t Count(void);  
    HRESULT GetInfoByIndex(size_t index, [out] ISummaryInfo **ppSummary);  
    HRESULT GetInfoByKey(LPCTSTR key, [out] ISummaryInfo **ppSummary);  
};  

不应直接使用此接口。 请改用 IFormController

ITSVariableBag 接口

__interface ITSVariableBag : IUnknown  
{  
    void GetValue([in] LPCTSTR variableName, [out] LPBSTR pValue);  
    void SetValue([in] LPCTSTR variableName, [in] LPCTSTR pValue);  
    void Clear(void);  
    HRESULT Remove([in] LPCTSTR variableName);  
    HRESULT SuppressLogValue([in] LPCTSTR variableName);  
    void Save(void);  
};  

此接口提供对任务序列变量的访问。 可以使用页面的 TSVariables () 方法访问此接口。

void GetValue ([in] LPCTSTR variableName, [out] LPBSTR pValue)

此方法读取任务序列变量的值。

注意

值在第一次读取后缓存。

void SetValue ([in] LPCTSTR variableName, [in] LPCTSTR pValue)

此方法设置任务序列变量的值。 此值保存在内存中。 在 UDI 向导中单击“ 完成 ”后,将写入任务序列值。

void 清除 (void)

此方法删除已保存在内存中的所有任务序列值。

HRESULT Remove ([in] LPCTSTR variableName)

此方法从内存中删除特定的任务序列值。 下次使用相同的任务序列名称调用 GetValue 时,该方法会尝试从任务序列中检索它。

HRESULT SuppressLogValue ([in] LPCTSTR variableName)

每当写入任务序列变量时(例如,在 UDI 向导中单击“ 完成 ”)时,名称和值将写入日志文件。 调用此方法可禁止记录特定任务序列变量的敏感值,例如密码或 PIN。

void 保存 (void)

此方法保存已通过调用 SetValue 设置的所有任务序列值。

ITSVariableRepository 接口

__interface ITSVariableRepository : IUnknown  
{  
    void GetValue([in] LPCTSTR variableName, BOOL logValue, [out] LPBSTR pValue);  
    void SetValue([in] LPCTSTR variableName, BOOL logValue, [in] LPCTSTR value);  
};  

此接口供 TSVariableBag 内部用于读取和写入任务序列变量。

IWizardFinish 接口

__interface IWizardFinish : IUnknown  
{  
    HRESULT Canceled(void);  
    HRESULT Finished(void);  
};  

在高级方案中,在 UDI 向导中单击“ 完成 ”或“ 取消 ”时,此接口非常有用。 UDI 向导包含一个 “完成” 任务,该任务在单击“ 完成”时保存任务序列变量。 如果取消向导,则任务仅将 OSDSetupWizCancelled 任务序列变量设置为 TRUE,并且不会保存对任何其他任务序列变量的更改。

如果创建自己的完成组件,则需要使用如下所示的代码注册它:

Register<MyFinishTaskFactory>(ID_MyFinishTask, pRegistry);  

PWizardFinish pFinish;  
CreateInstance(pRegistry, ID_MyFinishTask, &pFinish);  

PWizardFinishService pService;  
GetService<IWizardFinishService>(pRegistry, &pService);  

pService->Register(pFinish);  

IBindableList 接口

__interface IBindableList : IUnknown  
{  
    size_t Count(void);  
    HRESULT GetCaption(size_t index, LPBSTR pCaption);  
};  

如果你有一个要通过调用 Bind 方法绑定到 组合框的数据源组件,则实现此接口。

size_t计数 (void)

此方法返回列表中的项数。

HRESULT GetCaption (size_t 索引,LPBSTR pCaption)

此方法返回特定索引处的项的标题。

IDataNodes 接口

__interface IDataNodes : IUnknown  
{  
    size_t Count();  
    HRESULT SetCaptionProperty(LPCTSTR captionProperty);  
    HRESULT GetProperty(size_t index, LPCTSTR propertyName, [out] LPBSTR propertyValue);  
    HRESULT GetNode(size_t index, [out] ISettingsProperties **ppNode);  
};  

此接口提供对可保存在页面中的分层数据的访问。 可以通过 ISettingsProperties 接口上的方法获取此接口,该接口可通过 Settings 方法提供给页面。

页面的 XML 中的数据可能如下所示

      <Data Name="Network">  
        <DataItem>  
          <Setter Property="DisplayName">Public</Setter>  
          <Setter Property="Share">\\servername\Share</Setter>  
        </DataItem>  
        <DataItem>  
          <Setter Property="DisplayName">Dev Team</Setter>  
          <Setter Property="Share">\\servername\DevShare</Setter>  
        </DataItem>  
      </Data>  

调用 Settings () -GetDataNode> (L“Network”, &pData) 会提供具有两个数据项的 IDataNodes 实例, (每个实例又具有两个) 属性。

size_t Count ()

此方法返回 DataItem 元素的数目。

HRESULT SetCaptionProperty (LPCTSTR captionProperty)

支持此接口的组件还支持 IBindableList,这样可以轻松地使用页面 XML 中的数据填充组合框。 此方法控制每个 DataItem 元素中的哪个属性 (资源库) 将用于此绑定。 例如,可以使用 DisplayName 调用此方法,并且它将使用该 setter 属性进行数据绑定。 然后,组合框将 “公共 团队”和 “开发团队 ”作为项包含在内。

HRESULT GetProperty (size_t index, LPCTSTR propertyName, [out] LPBSTR propertyValue)

此方法从其中一个 DataItem 元素获取属性。 请参阅表 41 和表 42。

表 41. DataItem GetProperty

参数 说明
"索引" 索引值 (从要检索其属性值的 DataItem 的 0) 开始
PropertyName 要检索其值的 setter 属性的名称
propertyValue 返回时,包含属性的字符串值

表 42. HRESULT GetProperty

[HRESULT] 说明
S_OK 已检索属性。
E_INVALIDARG 索引超过数组的末尾。
HRESULT GetNode (size_t index, [out] ISettingsProperties **ppNode)

此方法类似于 GetProperty,但不是从 DataItem 返回一个值,而是返回包装在 ISettingsProperties 接口中的整个 DataItem。 请参阅表 43 和表 44。

表 43. HRESULT GetNode

参数 说明
索引 索引值 (从要检索其属性值的 DataItem 的 0) 开始
ppNode 退出时,包装 DataItem 节点的 ISettingsProperties 接口

表 44. HRESULT GetNode 结果

[HRESULT] 说明
S_OK 已检索节点。
E_INVALIDARG 索引超过数组的末尾。

IFactoryRegistry 接口

__interface IFactoryRegistry : IUnknown  
{  
    void Register(LPCTSTR type,  IClassFactory *pFactory);  
    HRESULT LoadAndRegister(LPCTSTR dllName, ILogger *pLogger);  
    BOOL Contains(LPCTSTR type);  
    HRESULT GetFactory(LPCTSTR type,  IClassFactory **ppFactory);  
    HRESULT CreateInstance(LPCTSTR type,  IUnknown **ppInstance);  
    HRESULT SetContainer(IWizardPageContainer *pContainer);  
    HRESULT RegisterService(REFGUID iid, IUnknown *pService);  
    HRESULT GetService(REFGUID iid,  IUnknown **ppService);  
};  
概览

创建新的自定义页面时,至少需要创建 一个页面工厂-一个实现 IClassFactory 的类。 (可以使用 ClassFactoryImpl 作为 factory.)

void Register (LPCTSTR type,IClassFactory *pFactory)

此方法向注册表注册类工厂。 请参阅表 45。

表 45. IClassFactory void Register

参数 说明
类型 标识要注册的工厂的字符串;通常,此参数应在字符串中具有公司名称,以确保它是唯一的
pFactory 指向类工厂实例的指针
HRESULT LoadAndRegister (LPCTSTR dllName,ILogger *pLogger)

此方法仅供内部使用。

BOOL 包含 (LPCTSTR 类型)

此方法通常供内部使用。 它会检查是否已为类型注册类工厂。

HRESULT GetFactory (LPCTSTR type,IClassFactory **ppFactory)

此方法允许检索类工厂。 通常,你会调用 CreateInstance。 但是,如果要创建大量相同的组件,则检索工厂,然后要求它为你创建实例会更有效。

HRESULT CreateInstance (LPCTSTR 类型,IUnknown **ppInstance)

此方法根据组件的类型创建一个新实例。 请改用 CreateInstance 模板方法,该方法允许创建类型安全的对象。

HRESULT SetContainer (IWizardPageContainer *pContainer)

此方法仅供内部使用。

HRESULT RegisterService (REFGUID iid, IUnknown *pService)

服务 是可在多个位置使用的组件的单个实例。 可以使用此方法在一页上注册服务,然后从另一页检索同一实例。

HRESULT GetService (REFGUID iid, IUnknown **ppService)

此方法检索以前通过对 RegisterService 的调用注册的服务。

HRESULT SetLanguage (LANGID languageId)

此方法将 UDI 向导的语言设置为在 languageId 参数中提供的语言标识符。

LANGID GetLanguage ()

此方法返回随 UDI 向导的 /locale 命令行参数提供的语言标识符的值。 方法返回以下值之一:

  • 随 /locale 命令行参数提供的语言标识符的值

  • 0,如果未提供 /locale 命令行参数

ILogger 接口

__interface ILogger : IUnknown  
{  
    HRESULT Init(LPCWSTR logFilename);  
    HRESULT MoveLog(LPCWSTR logFilename);  
    HRESULT LogBase(EMessageType messageType, LPCTSTR component, SYSTEMTIME eventTime, LPCTSTR message);  
    HRESULT Log(EMessageType messageType, LPCTSTR component, LPCTSTR message);  
    HRESULT Error(HRESULT error, LPCTSTR component, LPCTSTR message);  
    HRESULT Error2(HRESULT error, LPCTSTR component, LPCTSTR message, LPCTSTR message2);  
    HRESULT Normal(LPCTSTR component, LPCTSTR message);      
    HRESULT Normal2(LPCTSTR component, LPCTSTR message, LPCTSTR message2);  
    HRESULT Verbose(LPCTSTR component, LPCTSTR message);  
    HRESULT Verbose2(LPCTSTR component, LPCTSTR message, LPCTSTR message2);  
    HRESULT Debug(LPCWSTR component, LPCWSTR message);  
    HRESULT EnableDebug(BOOL debug);  
    HRESULT Close(void);  
    HRESULT GetLogFilename(LPBSTR pFilename);  
};  
概览

UDI 向导将信息记录到日志文件中,这有助于排查字段中发现的问题。 最好让页面记录信息。 可以使用页面的 Logger () 方法从页面内获取指向此接口的指针。 日志文件中的行包含表示错误、正常、详细或调试消息的“级别”数字。

注意

除非启用调试支持,否则调试消息不会保存到日志文件。 可以通过将以下行添加到 .config 文件中的 Style 元素来启用调试支持:

<Setter Property="debug">true</Setter>  
初始
HRESULT Init(LPCWSTR logFilename)  

此方法仅供内部使用。

MoveLog
HRESULT MoveLog(LPCWSTR logFilename)  

此方法仅供内部使用。

LogBase
HRESULT LogBase(EMessageType messageType, LPCTSTR component, SYSTEMTIME eventTime, LPCTSTR message)  

此方法仅供内部使用。

Log
HRESULT Log(EMessageType messageType, LPCTSTR component, LPCTSTR message)  

此方法仅供内部使用。

Error
HRESULT Error(HRESULT error, LPCTSTR component, LPCTSTR message)  

调用此方法可记录有关错误的信息。 请参阅表 46。

表 46. HRESULT 错误

参数 说明
错误 调用返回的错误代码 (此代码将以数字的形式显示在日志条目中。)
组件 标识错误来源的字符串,通常是你的页面或你编写的组件
邮件 说明导致错误的原因的消息
Error2
HRESULT Error2(HRESULT error, LPCTSTR component, LPCTSTR message, LPCTSTR message2)  

此方法类似于 Error 方法,但允许提供由两部分构成的消息。 最终消息将在输出文件中具有“message”,然后为“message2”。 这只是一种方便的方法。

一般
HRESULT Normal(LPCTSTR component, LPCTSTR message)  

此方法记录正常消息。 有关参数,请参阅 Error 方法的说明。

Normal2
HRESULT Normal2(LPCTSTR component, LPCTSTR message, LPCTSTR message2)  

此方法记录正常消息。 有关参数,请参阅 Error2 方法的说明。

Verbose
HRESULT Verbose(LPCTSTR component, LPCTSTR message)  

此方法记录详细消息。 有关参数,请参阅 Error 方法的说明。

Verbose2
HRESULT Verbose2(LPCTSTR component, LPCTSTR message, LPCTSTR message2)  

此方法记录详细消息。 有关参数,请参阅 Error2 方法的说明。

调试
HRESULT Debug(LPCWSTR component, LPCWSTR message)  

此方法记录调试消息。 有关参数,请参阅 Error 方法的说明。 除非启用,否则调试消息不会保存到文件中。 有关详细信息,请参阅概述部分。

EnableDebug
HRESULT EnableDebug(BOOL debug)  

此方法仅供内部使用。

关闭
HRESULT Close(void)  

此方法仅供内部使用。

GetLogFilename
HRESULT GetLogFilename(LPBSTR pFilename)  

此方法检索日志文件的名称。

IOrientation 接口

__interface IOrientation : IUnknown  
{  
    void SetController(IWizardDialogController *pController);  
    int AddPage(LPCTSTR name);  
    void SelectPage(int index);  
};  

此接口仅供内部使用。

ISettings 接口

__interface ISettings : IUnknown  
{  
    int NumDlls();  
    int NumPages();  

    HRESULT SetStage(LPCWSTR stageName);  
    HRESULT GetDllName(long index, __out LPBSTR pDllName);  
    HRESULT GetPageInfo(long index, __out ISettingsProperties **ppPageInfo);  
    HRESULT GetStyle(__out ISettingsProperties **ppStyleInfo);  
};  

此接口仅供内部使用。

ISettingsProperties 接口

__interface ISettingsProperties : IUnknown  
{  
    HRESULT GetAttribute(LPCTSTR attributeName, __out LPBSTR attributeValue);  
    IStringProperties * Properties();  
    HRESULT SelectNodes(LPCTSTR xPath, __out IXMLDOMNodeList **ppList);  
    HRESULT SelectSingleNode(LPCTSTR xPath, __out IXMLDOMNode **ppNode);  
    HRESULT GetDataNode(LPCTSTR name, __out ISettingsProperties **ppNode);  
    HRESULT GetDataNodes(__out IDataNodes **ppNodes);  
    HRESULT GetChildDataNodes(LPCTSTR childeName, __out IDataNodes **ppNodes);  
};  
概览

此接口提供对页面数据的访问。 若要获取页面数据的顶级,请使用页面的 Settings () 方法。

HRESULT GetAttribute (LPCTSTR attributeName、LPBSTR attributeValue)

此方法允许检索主节点上的属性值,即使用页面的 Settings () 方法时的页面节点。

IStringProperties * Properties ()

此方法提供对主节点下的 setter 属性值的访问。 对于页面,这些是顶级属性。

HRESULT SelectNodes (LPCTSTR xPath, IXMLDOMNodeList **ppList)

如果要使用 XPath 表达式直接获取 XML 节点列表,请调用此方法。 如果可以,最好使用其他方法之一。 仅当无法以任何其他方式访问节点时,才使用此方法。

HRESULT SelectSingleNode (LPCTSTR xPath, IXMLDOMNode **ppNode)

如果要使用 XPath 表达式直接获取单个 XML 节点,请调用此方法。 如果可以,最好使用其他方法之一。 仅当无法以任何其他方式访问节点时,才使用此方法。

HRESULT GetDataNode (LPCTSTR 名称、ISettingsProperties **ppNode)

基于该元素的 Name 属性检索 Data 元素。

HRESULT GetDataNodes (IDataNodes **ppNodes)

此方法检索当前节点下的 DataItem 元素列表。 从页面级别调用 GetDataNode 以检索数据的 ISettingsProperty 接口。 然后,在该实例上调用 GetDataNodes 以检索记录列表。 例如,给定此 XML:

    <Page ...>  
      <Data Name="Network">  
        <DataItem>  
          <Setter Property="DisplayName">Public</Setter>  
          <Setter Property="Share">\\servername\Share</Setter>  
        </DataItem>  
        <DataItem>  
          <Setter Property="DisplayName">Dev Team</Setter>  
          <Setter Property="Share">\\servername\DevShare</Setter>  
        </DataItem>  
      </Data>  
PSettingsProperties pData;  
Settings()->GetDataNode(L"Network", &pData);  
PDataNodes pNodes;  
pData->GetDataNodes(&pNodes);  
HRESULT GetChildDataNodes (LPCTSTR childeName, IDataNodes **ppNodes)

此方法提供了一种快速访问特定数据节点下的 DataItem 节点集 的方法 。 使用 GetDataNodes 示例中的 XML,以下代码执行的操作与 GetDataNodes 下的示例中的四行代码完全相同,但会进行错误检查:

ISimpleStringProperties Interface  

ISimpleStringProperties 接口

__interface ISimpleStringProperties : IStringProperties  
{  
void Add(LPCTSTR propertyName, LPCTSTR value);  
};  

就本身而言,此接口可能没有用。 但是,它由 ID_SimpleStringProperties 组件实现,该组件也实现了 IStringProperties 接口。 如果需要将一组属性传递给另一个组件(例如任务),但希望以编程方式添加值,而不是使用 XML 中的值,则可以使用此组件。 下面是如何使用此接口的示例:

PSimpleStringProperties *pProperties;  
CreateInstance(Container(), ID_SimpleStringProperties, &pProperties);  
pProperties->Add(L"filename", L"%windir%\\system32\\cscript.exe");  
pTask->Init(pProperties, nullptr);  
IStringProperties  
__interface IStringProperties : IUnknown  
{  
    HRESULT Get(LPCTSTR propertyName, [out] LPBSTR pPropValue);  
};  

此接口提供对来自 XML 的一组 setter 元素的简单访问。 此接口可用于使用 Settings () -Properties> () 的页面的属性。

HRESULT 获取 (LPCTSTR propertyName, [out] LPBSTR pPropValue)

此方法检索单个属性值。 请参阅表 47 和表 48。

表 47. IHRESULT 获取属性值

参数 说明
PropertyName 要读取的属性的名称
pPropValue 退出时,将属性值作为字符串包含 (如果没有此类属性,此值将为 nullptr 。)

表 48. IHRESULT 获取属性值结果

[HRESULT] 说明
S_OK 检索属性值。
E_INVALIDARG 没有具有你提供的名称的属性。

ITaskManager 接口

__interface ITaskManager : IUnknown  
{  
    HRESULT Init(IWizardPageView *pPageView, int idListView, int idMessage, int idRetryButton, ISettingsProperties *pPageInfo, ITaskManagerCallback *pCallback);  
    HRESULT SetFailMessage(LPCWSTR message);  

    HRESULT Start(void);  

    HRESULT GetTaskMessage(size_t index, LPBSTR message);  
    HRESULT GetResultType)(size_t index, LPBSTR type);  
    HRESULT GetProperty(size_t index, LPCTSTR propertyName, LPBSTR value);  
    int GetSelectedIndex(void);  
    HRESULT Wait(DWORD waitMilliseconds);  
    size_t FailedCount(void);  
    size_t WarningCount(void);  
    size_t SucceedCount(void);  
    size_t RunningCount(void);  

    void OnCommonControlEvent(WORD controlId, LPNMHDR pInfo);  
    void OnControlEvent(WORD eventId, WORD controlId);  
    void EnableButtons(BOOL enable);  
}  

此接口由 ITaskManager.h) 中的 TaskManager 组件 (ID_TaskManager 实现,后者是在预检页上运行任务的组件。 可以直接使用预检页(这是你大部分时间所执行的操作),也可以生成自己的页面,让此组件完成大部分工作。

HRESULT Init (IWizardPageView *pPageView, int idListView, int idMessage, int idRetryButton, ISettingsProperties *pPageInfo, ITaskManagerCallback *pCallback)

在调用任何其他方法之前,必须调用此方法。 它初始化 TaskManager 组件。 请参阅表 49。

表 49. HRESULT Init

参数 说明
pPageView 提供对将运行任务的页面的访问权限, (此页面必须具有一组特定的控件,这些控件将在接下来的几个参数中概述。)
idListView ListView 控件的控件 ID,该控件将显示任务列表和这些任务的状态
idMessage 文本框的控件 ID,该文本框将用于显示所选任务的消息
idRetryButton 可以单击以再次运行任务的按钮的控件 ID
pPageInfo 围绕页面 XML 的包装 (TaskManager 加载要从此 XML 运行的任务集。)
pCallback 可以为 null (如果此参数不为 null, 则 TaskManager 在启动任务时调用 Started 方法,并为完成 running 的每个任务调用 Finished 方法。)
HRESULT SetFailMessage (LPCWSTR 消息)

此方法设置在一个或多个任务失败时将显示的消息。

HRESULT Start (void)

此方法启动所有任务。 每个任务在单独的线程上启动。

HRESULT GetTaskMessage (size_t 索引、LPBSTR 消息)

此方法仅供内部使用。 它根据任务列表中的索引检索任务的当前消息。

HRESULT GetResultType) (size_t index,LPBSTR 类型)

此方法检索任务的当前“类型”。 表 50 显示了可用类型。

表 50. HRESULT GetResultType

类型 说明
0 表示成功的任务
1 表示返回警告的任务
-1 表示失败的任务

通过查看任务的退出或错误代码并在任务的 ExitCodes> XML 元素中<查找匹配项来检索类型。

HRESULT GetProperty (size_t index、LPCTSTR propertyName、LPBSTR 值)

进度页和预检页使用此方法检索 BitmapFilename setter 属性,以便它可以在突出显示的任务的消息旁边显示图像。 换句话说,可以将自定义资源库添加到任务的 XML,然后使用此方法检索它。

int GetSelectedIndex (void)

此方法检索当前所选任务的索引,如果要检索有关任务的其他信息 (请参阅要为所选任务显示的 GetProperty 方法) ,此方法非常有用。 进度页和预检页使用此方法显示所选任务的图像。

HRESULT Wait (DWORD waitMilliseconds)

此方法主要有助于进行单元测试,以便测试可以确保任务在单元测试退出之前完成。 通常不会调用此方法。 当所有任务完成运行或等待时间已过时,它将返回 。

size_t FailedCount (void)

此方法返回当前标记为失败的任务数。

size_t WarningCount (void)

此方法返回当前标记为警告的任务数。

size_t SucceedCount (void)

此方法返回当前标记为成功的任务数。

size_t RunningCount (void)

此方法返回当前正在运行的任务数。

void OnCommonControlEvent (WORD controlId、LPNMHDR pInfo)

从页面的 OnCommonControlEvent 调用此方法,以便 TaskManager 可以处理它所需的事件。

void OnControlEvent (WORD eventId,WORD controlId)

从页面的 OnControlEvent 调用此方法,以便 TaskManager 可以处理它所需的事件。

void EnableButtons (BOOL enable)

此方法仅供内部使用。

IWizardComponent 接口

__interface IWizardComponent : IUnknown  
{  
    HRESULT SetContainer(IWizardPageContainer *pContainer);  
};  
概览

通常,不会直接实现此接口,而是通过 WizardComponent 模板类实现。 如果组件实现了此接口,并且你已在注册表中注册了类工厂,则组件在创建时会收到指向 IWizardPageContainer 实例的指针。 例如,这有助于访问记录器或注册表,以创建组件可能需要的其他组件。

IWizardDialogController 接口

__interface IWizardDialogController : IUnknown  
{  
    void Initialize(ISettings *pSettings);  
    void InitPages(void);  
    void Start();  
    void Next();  
    void Finish();  
    void Previous();  
    int NumPages();  
    void Cancel();  

    HRESULT Focus(WizardButtons button);  
    HRESULT SetEnable(WizardButtons button, BOOL enable);  
    void ShowWarningMessage(LPCTSTR message);  
    void HideWarningMessage();  

    void ChangePage(size_t newIndex);  
    IUnknown *CurrentPage(void);  
    HRESULT GetCurrentTitle([out, retval] LPBSTR pDisplayName);  
};  

此接口仅供内部使用。

IWizardDialogView 接口

__interface IWizardDialogView : IUnknown  
{  
    HRESULT LoadBannerImage(LPCTSTR bannerFilename);  
    HRESULT LoadPage(LPCTSTR pageType, ISettingsProperties *pPageSettings, IWizardPageView **view);  
    HRESULT SetEnable(WizardButtons button, BOOL enable);  
    HRESULT Focus(WizardButtons button);  
    void EnableFinish(BOOL isFinish);  
    void Exit(int exitCode);  
    void ShowWarningMessage(LPCTSTR message);  
    void HideWarningMessage(void);  
    void SetTitle(LPCTSTR title);  
    void SetPageTitle(LPCTSTR title);  
    int ShowMessageBox(LPCTSTR message, LPCTSTR lpCaption, UINT uType);  
    HWND GetHwnd(void);  
    void UpdateFocus(void);  
};  

此接口仅供内部使用。

IWizardPage 接口

__interface IWizardPage : IUnknown  
{  
    HRESULT SetPageSettings(ISettingsProperties *pPageSettings);  
    HINSTANCE GetInstanceHandle(void);  
    int GetDialogResourceId(void);  
    void WindowCreated(IWizardPageView *pView, IWizardPageContainer *pContainer);  
    void WindowShown(void);  
    void WindowHidden(void);  

    HRESULT NextClicked(void);  
    void ControlEvent(WORD eventId, WORD controlId);  
    void CommonControlEvent(WORD controlId, LPNMHDR pInfo, LPBOOL pCancel);  
    void UnhandledEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);  
};  
概览

此接口由 WizardPageImpl 实现,因此通常无需自己实现此接口。 向导在与自定义页面交互时会为你调用所有这些方法。

IWizardPageContainer 接口

__interface IWizardPageContainer : IUnknown  
{  
    ILogger * Logger(void);  
    IPropertyBag * Properties(void);  
    HRESULT CreateInstance(LPCTSTR type, [out] IUnknown **ppInstance);  
    HRESULT GetService(REFIID iid, [out] IUnknown **ppInstance);  
    HRESULT ReplaceVariables(LPCTSTR source, [out] LPBSTR pDest);  
    HRESULT GotoPage(LPCTSTR pageName);  
    int ShowMessageBox(LPCTSTR message, LPCTSTR lpCaption, UINT uType);  
    BOOL InPreview(void);  
    HWND GetHwnd(void);  
};  
概览

此接口可通过 WizardPageImpl) 实现的 Container 方法 (提供给页面,并允许您访问向导的各种服务。

ILogger * Logger (void)

使用此方法将消息写入日志文件,例如:

Logger()->Verbose(s_component, L"Message for log file");  
IPropertyBag * 属性 (void)

此方法提供对“内存”变量的访问权限,这些变量是仅在 UDI 向导运行时内存中的属性。 这些属性可用于使用 $memoryVarName$ 语法在代码或 XML 中的其他页面。

HRESULT CreateInstance (LPCTSTR 类型[out] IUnknown **ppInstance)

此方法允许创建已注册的任何组件的新实例。 但是,最好使用模板函数 CreateInstance,因为它已强类型化。

HRESULT GetService (REFIID iid, [out] IUnknown **ppInstance)

此方法允许检索已注册的服务。 但是,最好调用 GetService 模板函数,该函数 (强类型,而不是使用 IUnknown) 。

HRESULT ReplaceVariables (LPCTSTR 源,[out] LPBSTR pDest)

此方法处理字符串值内变量的处理。 它支持表 51 和表 52 中显示的格式。

表 51. HRESULT ReplaceVariables

Format 说明
$Name$ 将内存变量的值替换为此名称 (如果没有名称的内存变量,则将删除“token”。)
%Name% 任务序列变量或环境变量。 顺序如下:

1. 使用任务序列变量的值(如果存在)。
2. 使用环境变量的值(如果存在)。
3.否则,请从字符串中删除此文本。

表 52. HRESULT 参数

参数 说明
Source 输入字符串,可以包含 和 % 变量的$任意组合,或者根本不包含任何变量
pDest 返回时,包含一个新字符串,该字符串已根据表 51 替换所有标记
HRESULT GotoPage (LPCTSTR pageName)

此方法尚未经过全面测试。 其思路是,可以根据.config XML 文件中定义的页面名称直接切换到特定页面。 调用此方法会绕过页面上的 OnNextClicked 。 此外,此方法的行为可能会发生更改,因此请自行承担风险。

int ShowMessageBox (LPCTSTR 消息,LPCTSTR lpCaption,UINT uType)

此方法显示一个消息框,其中包含你提供的文本和标题。 uType 参数是可以提供给 MessageBox Win32 函数的任何值。

BOOL InPreview (void)

如果通过提供 /preview 开关在“预览”模式下启动向导,则此方法返回 TRUE。 在预览模式下,永远不会禁用 “下一步 ”按钮。 此方法允许在预览模式下绕过代码,例如,当页面上没有有效数据时,这些代码可能会导致问题。

HWND GetHwnd (void)

此方法返回主对话框的 HWND 。 谨慎使用此方法。 通常,UDI 向导应用程序编程接口旨在使你永远不会直接使用窗口句柄。

IWizardPageView 接口

__interface IWizardPageView : IUnknown  
{  
    HRESULT GetControlWrapper(int itemId, DialogControlTypes controlType, IUnknown **ppControl);  
    HWND GetHwnd(void);  
    HWND GetControl(int itemId);  
    HRESULT Show (void);  
    HRESULT Hide(void);  
    HRESULT Focus(int itemId);  
    IWizardPage * Page(void);  
    IFormController * Form(void);  

    HRESULT FocusWizardButton(WizardButtons button);  
    HRESULT SetEnable(WizardButtons button, BOOL enable);  
    void ShowWarningMessage(LPCTSTR message);  
    void HideWarningMessage(void);  
};  

此接口可通过 View 方法 (WizardPageImpl) 实现的页面中的代码使用。

HRESULT GetControlWrapper (int itemId, DialogControlTypes controlType, IUnknown *ppControl)

UDI 向导使用 包装器,包装器实际上是用于与页面上的控件进行交互的外墙。 使用这些外观而不是实际控件可以更轻松地为页面编写测试,因为可以从测试中提供模拟外观。

最好使用强类型化 GetControlWrapper 模板方法,而不是直接使用此方法,例如:

PComboBox m_pLanguagePackCombo;  
GetControlWrapper(View(), IDC_MY_COMBO, CONTROL_COMBO_BOX, &m_pCombo);  
HWND GetHwnd (void)

此方法返回页面的窗口句柄。 通常,不应需要访问此窗口句柄。

HWND GetControl (int itemId)

如果需要,可以调用此方法来获取页面上控件的窗口句柄。 (最好) 调用 GetControlWrapper 模板函数。

HRESULT 显示 (void)

此方法仅供内部使用。

HRESULT 隐藏 (void)

此方法仅供内部使用。

HRESULT Focus (int itemId)

将输入焦点设置为特定控件。

IWizardPage * Page (void)

此方法仅供内部使用。

IFormController * Form (void)

此方法仅供内部使用。

HRESULT FocusWizardButton (WizardButtons 按钮)

将焦点设置为向导的按钮之一。WizardButtons 有两个值: BackButtonNextButton

HRESULT SetEnable (WizardButtons 按钮,BOOL 启用)

请求启用或禁用其中一个向导按钮。 按钮可能与请求的状态不匹配。 例如,如果使用 /preview 开关运行 UDI 向导,将始终启用按钮。 WizardButtons 有两个值: BackButtonNextButton

void ShowWarningMessage (LPCTSTR 消息)

此方法在页面内容区域底部显示警告消息。 此消息可以是所需的任何文本。

void HideWarningMessage (void)

隐藏调用 ShowWarningMessage 时显示的警告消息。

IXmlDocument 接口

__interface IXmlDocument : IUnknown  
    HRESULT Load(LPCTSTR filename);  
    HRESULT LoadXml(LPCTSTR xml);  
    HRESULT Save(LPCWSTR filename);  
    HRESULT GetParseErrorMessage(LPBSTR pMessage);  
    HRESULT SelectNodes(LPCTSTR xpath, IXMLDOMNodeList **ppNodes);  
    HRESULT SelectSingleNode(LPCTSTR xpath, IXMLDOMNode **ppNode);  
    HRESULT AddSchema(LPCTSTR filename, LPCTSTR ns);  
    HRESULT AddAttribute(IXMLDOMNode *pNode, LPCWSTR name, LPCWSTR value);  
    HRESULT CreateNode(DOMNodeType type, LPCWSTR name, LPCWSTR ns, IXMLDOMNode **ppNode);  
};  
概览

此接口由 ID_IXmlDocument 组件实现,该组件是一个外观,旨在更轻松地使用 C++ 中的 XML 文档。

HRESULT 加载 (LPCTSTR 文件名)

此方法从外部文件加载 XML 文档。 如果加载文件时没有错误,则返回 S_OK ;如果发生错误, 则返回S_FALSE 。 出现错误时,可以通过调用 GetParseErrorMessage 获取错误消息。

HRESULT LoadXml (LPCTSTR xml)

此方法从字符串而不是外部文件加载 XML 文档。 除了用于读取 XML 的源之外,该行为与 Load 方法相同。

HRESULT 保存 (LPCWSTR 文件名)

此方法将内存中的 XML 文档保存到外部文件。

HRESULT GetParseErrorMessage (LPBSTR pMessage)

此方法返回一个新字符串,其中包含加载 XML 文档时出现错误消息(如果有)。 它始终返回 S_OK

HRESULT SelectNodes (LPCTSTR xpath, IXMLDOMNodeList **ppNodes)

此方法允许使用 XPath 表达式从文档检索节点集合。 它始终返回 S_OK

HRESULT SelectSingleNode (LPCTSTR xpath, IXMLDOMNode **ppNode)

此方法允许使用 XPath 表达式从文档中检索一个节点。 它始终返回 S_OK

HRESULT AddSchema (LPCTSTR 文件名,LPCTSTR ns)

此方法添加外部架构文件的名称,该文件将用于在加载 XML 文档时验证该文档的架构。 提供的命名空间是可在 XPath 查询中使用的字符串,尽管尚未对此进行测试。

HRESULT AddAttribute (IXMLDOMNode *pNode, LPCWSTR 名称, LPCWSTR 值)

此方法将新属性添加到 XML 文档中的现有节点。 请参阅表 53。

表 53. HRESULT AddAttribute

参数 说明
pNode 要向其添加特性的节点
名称 新属性的名称
新属性的值
HRESULT CreateNode (DOMNodeType 类型、LPCWSTR 名称、LPCWSTR ns、IXMLDOMNode **ppNode)

调用此方法以创建新节点:

Pointer<IXMLDOMNode> pNewChild  
pXmlDom->CreateNode(NODE_ELEMENT, L"MyElement", L"", &pNewChild);  

创建新节点后,可以通过调用父级的 appendChild 方法将其作为子节点添加到另一个节点。

帮助程序函数

CreateInstance 模板函数

HRESULT CreateInstance(IWizardPageContainer *pContainer, LPCTSTR type, I **ppObject)  

此函数在 IWizardPageContainer.h 中定义,并通过 IWizardPageContainer-CreateInstance> 方法提供类型安全的包装器,例如:

CreateInstance<IDirectory>(Container(), ID_Directory, &pDirectory);  

此代码创建一个新的 ID_Directory 组件来检索该组件的 IDirectory 接口。

GetService 模板函数

void GetService(IWizardPageContainer *pContainer, I **ppService)  

此函数在 IWizardPageContainer.h 中定义,并通过 IWizardPageContainer-GetService> 方法提供类型安全的包装器,例如:

GetService<ITSVariableBag>(Container(), &pTsBag);  

此函数检索支持 ITSVariableBag 接口的任务序列组件。 (对于 ITSVariableBag,可以改用 WizardPageImpl 类的 TSVariables 方法。)

UDI 向导设计器配置文件架构参考

此文件由 UDI 向导设计器使用。 为每个自定义.dll文件创建一个单独的文件,该文件可以包含自定义向导页编辑器、自定义任务或自定义验证程序。 该文件必须以 .config 结尾,并且驻留在 installation_folder\Bin\Config 文件夹中, (其中installation_folder 是安装 MDT) 的文件夹。

表 54 列出了 UDI 向导设计器配置文件中的元素及其说明。 DesignerConfig 元素是此引用的根节点。

表 54. UDI 向导设计器配置文件中的元素及其说明

元素名称 说明
DesignerConfig 指定所有其他元素的根
DesignerMappings 对一组 Page元素进行分组
Page 指定要在 UDI 向导设计器中加载的向导页编辑器,该编辑器用于编辑向导页的配置设置
Param 指定传递给父 TaskValidator 元素的参数,该参数对应于 UDI 向导配置文件中的 Setter 元素 注意: 如果父元素是 TaskValidator 元素,则此元素的属性不同。
任务 指定任务库中的任务
TaskItem 指定传递给任务的一组参数
TaskLibrary 对一组 Task 元素进行分组
验证 指定验证程序库中的验证程序
ValidatorLibrary 对一组 验证器 元素进行分组

DesignerConfig

此元素指定所有其他元素的根。

元素信息

表 55 提供了有关 DesignerConfig 元素的信息。

表 55. DesignerConfig 元素信息

属性
出现次数 一:此元素是必需的。
父元素
目录 DesignerMappingsTaskLibraryValidatorLibrary
元素属性

此元素没有属性。

备注

无。

示例
<DesignerConfig>  
   + <TaskLibrary>  
   + <ValidatorLibrary>  
   + <DesignerMappings>  
</DesignerConfig>  

DesignerMappings

此元素对一组 Page 元素进行分组。

元素信息

表 56 提供了有关 DesignerMappings 元素的信息。

表 56. DesignerMappings 元素信息

属性
出现次数 DesignerConfig 元素中的零个或一个 (如果 DLL 中没有与此 UDI 向导设计器配置文件对应的自定义向导页,则此元素是可选的。)
父元素 DesignerConfig
目录 Page
元素属性

此元素没有属性。

备注

无。

示例
<DesignerConfig>  
   + <TaskLibrary>  
   + <ValidatorLibrary>  
   - <DesignerMappings>  
        <Page DLL="SharedPages.dll"  
           Description="Used to display text that describes the current stagegroup"  
           Type="Microsoft.SharedPages.WelcomePage"  
           DisplayName="Welcome"   
           Image="Welcome_188.png"  
           DesignerType="Microsoft.Enterprise.UDIDesigner.CoreModules.Views.WelcomePageView"  
           DesignerAssembly="Microsoft.Enterprise.UDIDesigner.CoreModules.dll"/>  
        <Page DLL="OSDRefreshWizard.dll"  
           Description="Captures or restores user state data"  
           Type="Microsoft.OSDRefresh.UserStatePage"  
           DisplayName="User Data"  
           Image="UserState_188.png"  
           DesignerType="Microsoft.Enterprise.UDIDesigner.CoreModules.Views.UserStatePageView"  
           DesignerAssembly="Microsoft.Enterprise.UDIDesigner.CoreModules.dll"/>  
        <Page DLL="OSDRefreshWizard.dll"  
           Description="Allows selecting the image to install, target drive, and whether to format"  
           Type="Microsoft.OSDRefresh.VolumePage"  
           DisplayName="Volume"  
           Image="Volume_188.png"  
           DesignerType="Microsoft.Enterprise.UDIDesigner.CoreModules.Views.VolumePageView"  
           DesignerAssembly="Microsoft.Enterprise.UDIDesigner.CoreModules.dll"/>  
     </DesignerMappings>  
</DesignerConfig>  

Page

此元素指定要在 UDI 向导设计器中加载的向导页编辑器,该编辑器又用于编辑向导页的配置设置。

元素信息

表 57 提供了有关 Page 元素的信息。

表 57. Page 元素信息

属性
出现次数 DesignerMappings 元素中定义的每个向导页的一个或多个
父元素 DesignerMappings
目录 任何格式正确的 XML 内容
元素属性

表 58 列出了 Page 元素的属性以及每个属性的说明。

表 58. Page 元素的属性和相应值

属性 说明
说明 指定提供有关参数的信息的文本,该参数显示在 UDI 向导设计器中
DesignerAssembly 指定与向导页编辑器关联的.dll文件的名称 (.dll 文件必须存在于 installation_folder\Bin 文件夹中 (其中 installation_folder 是安装 MDT.)
DesignerType 指定在 DesignerAssembly 属性中指定的 .dll 文件中向导页编辑器的名称 (这是向导页编辑器的Microsoft .NET 类型,具有完全限定Microsoft .NET namespace.)
DisplayName 指定页面编辑器的用户友好名称,该名称显示在 UDI 向导设计器中
Dll 指定与向导页关联的.dll文件的名称 (.dll文件必须存在于 installation_folder\Templates\Distribution\Tools\platform 文件夹中 (其中 installation_folder 是安装 MDT 的文件夹, 平台 是 32 位版本的 x8664 位版本的 x64 。) 注意: 确保 DLL 处理器体系结构与安装的 MDT 处理器体系结构匹配。 例如,如果安装了 32 位版本的 MDT,请确保对向导页使用 32 位 DLL。
图像 指定可移植网络图形 (PNG) 格式 (.png文件必须存在于 installation_folder\Bin\Images 文件夹中 (其中installation_folder 是安装 MDT.)
类型 指定向导页编辑器,并且必须与注册自定义页时使用的命名匹配
备注

UDI 向导设计器使用 Page 元素(如模板)为新向导创建初始 XML。 UDI 向导设计器执行架构验证,以确保 Page 和子元素具有有效的格式。 此元素提供 UDI 向导页类型与 UDI 向导设计器使用自定义页面编辑器编辑和创建此类型的页面所需的信息之间的映射。

示例

无。

参数

此元素指定传递给父 TaskValidator 元素的参数,该参数对应于 UDI 向导配置文件中的 Setter 元素。

注意

如果父元素是 TaskValidator 元素,则此元素的属性会有所不同。

元素信息

表 59 提供了有关 Param 元素的信息。

表 59. 参数元素信息

属性
出现次数 每个 TaskItemValidator 父元素的一个或多个
父元素 TaskItem验证器
目录 任何格式正确的 XML 内容
元素属性

表 60 列出了 Param 元素的属性,并提供了每个属性的说明。

表 60. 参数元素的属性和相应值

属性 说明
说明 指定提供有关 参数的信息的文本,该参数显示在 UDI 向导设计器 注意: 此属性仅对 验证器 元素有效。
DisplayName 指定验证程序参数的用户友好名称,该名称在 UDI 向导设计器中为相应的 UDI 向导页显示 (此名称通常比 Name 属性更具描述性。) 注意: 此属性仅对 验证器 元素有效。
名称 指定传递给任务或验证程序的参数的名称,具体取决于父元素 (此属性将成为 UDI 向导配置文件中的 Setter 元素中的 Property 属性。) 注意:此参数同时用于 TaskItemValidator 父元素。
备注

无。

示例

无。

任务

此元素指定任务库中的任务。

元素信息

表 61 提供了有关 Task 元素的信息。

表 61. 任务元素信息

属性
出现次数 TaskLibrary 元素中的一个或多个 (如果指定了 TaskLibrary 元素,则此元素不是可选的。)
父元素 TaskLibrary
目录 TaskItem
元素属性

表 62 列出了 Task 元素的属性,并提供了每个属性的说明。

表 62. Task 元素的属性和相应值

属性 说明
说明 指定提供有关任务信息的文本,该任务显示在 UDI 向导设计器中
Dll 指定与任务关联的.dll文件的名称 (.dll 文件必须存在于 installation_folder\Templates\Distribution\Tools\platform 文件夹中 (其中 installation_folder 是安装 MDT 的文件夹,平台 对于 32 位版本为 x86 ,对于 64 位版本为 x64 。)
名称 指定任务的名称,该名称显示在相应的 UDI 向导页和 UDI 向导设计器中
类型 指定任务类型,该类型在工厂注册表中注册并用于调用.dll文件中的特定任务
备注

无。

示例

无。

TaskItem

此元素指定传递给任务的一组参数。

元素信息

表 63 提供了有关 TaskItem 元素的信息。

表 63. TaskItem 元素信息

属性
出现次数 每个 Task 元素有一个或多个
父元素 任务
目录 Param
元素属性

表 64 列出了 TaskItem 元素的属性,并提供了每个属性的说明。

表 64. TaskItem 元素的属性和相应值

属性 说明
类型 指定将在 UDI 向导配置文件中创建的元素类型的 。 将创建一个对应于此属性的值的 XML 元素。 例如,如果此属性的值为 File,则会在 UDI 向导配置文件中创建 File 元素。

目前,仅支持以下值:

- 文件,它需要两个 Param 子元素 (一个 参数 子元素,其中 Name 属性设置为 Source ,另一个 参数 子元素的 Name 属性设置为 Dest)
- Setter,需要一个 Param 子元素
备注

无。

示例

无。

TaskLibrary

此元素对一组 Task 元素进行分组。

元素信息

表 65 提供了有关 TaskLibrary 元素的信息。

表 65. TaskLibrary 元素信息

属性
出现次数 DesignerConfig 元素中的零个或一个 (如果 DLL 中没有对应于此 UDI 向导设计器配置文件的自定义任务,则此元素是可选的。)
父元素 DesignerConfig
目录 任务
元素属性

此元素没有属性。

备注

无。

示例
<DesignerConfig>  
   - <TaskLibrary>  
        +<Task DLL="" Description="Executes a process with the given command line." Type="Microsoft.Wizard.ShellExecuteTask" Name="Shell Execute Task">  
        +<Task DLL="OSDRefreshWizard.dll" Description="Discovers supported applications for install." Type="Microsoft.OSDRefresh.AppDiscoveryTask" Name="Application Discovery">  
        +<Task DLL="SharedPages.dll" Description="Check to ensure a wired network connection is available." Type="Microsoft.SharedPages.WiredNetworkTask" Name="Wired Network Check">  
        +<Task DLL="OSDRefreshWizard.dll" Description="Check to ensure power source is AC (not battery)." Type="Microsoft.OSDRefresh.ACPowerTask" Name="AC Power Check">  
        +<Task DLL="" Description="Check to ensure power source is AC (not battery)." Type="Microsoft.Wizard.CopyFilesTask" Name="Copy Files Task">  
     </TaskLibrary>  
   + <ValidatorLibrary>  
   + <DesignerMappings>  
</DesignerConfig>  

验证

此元素指定验证程序库中的验证程序。

元素信息

表 66 提供了有关 验证器 元素的信息。

表 66. 验证器元素信息

属性
出现次数 ValidatorLibrary 元素中的零个或多个 (此元素是可选的。)
父元素 ValidatorLibrary
目录 Param
元素属性

表 67 列出了 验证器 元素的属性,并提供了每个属性的说明。

表 67. 验证器元素的属性和相应值

属性 说明
说明 指定提供有关验证程序的信息的文本,该信息显示在 UDI 向导设计器中
DisplayName 指定 UDI 向导设计器中显示的验证程序的用户友好名称 (此名称通常比 Name 属性更具描述性。)
Dll 指定与验证程序关联的.dll文件的名称 (.dll文件必须存在于 installation_folder\Templates\Distribution\Tools\platform 文件夹中 (其中 installation_folder 是安装 MDT 的文件夹,平台 是 32 位版本的 x8664 位版本的 x64。)
名称 指定验证程序的名称,该名称显示在相应的 UDI 向导页和 UDI 向导设计器中
类型 指定验证程序类型,该类型注册到注册表因子,并用于调用.dll文件中的特定验证程序
备注

无。

示例

无。

ValidatorLibrary

此元素对一组 验证器 元素进行分组。

元素信息

表 68 提供了有关 ValidatorLibrary 元素的信息。

表 68. ValidatorLibrary 元素信息

属性
出现次数 DesignerConfig 元素中的零个或一个 (如果 DLL 中没有对应于此 UDI 向导设计器配置文件的自定义验证程序,则此元素是可选的。)
父元素 DesignerConfig
目录 验证
元素属性

此元素没有属性。

备注

无。

示例

<DesignerConfig> + <TaskLibrary> - <ValidatorLibrary> +<Validator DLL=“” Description=“Requires text in a field” Type=“Microsoft。Wizard.Validation.NonEmpty“ Name=”NonEmpty“> +<Validator DLL=”“ Description=”不允许某些字符位于字段中“ Type=”Microsoft。Wizard.Validation.InvalidChars“ Name=”InvalidChars“> +<Validator DLL=”“ Description=”必须遵循预定义的模式“ Type=”Microsoft。Wizard.Validation.RegEx“ Name=”NamedPattern“> +<Validator DLL=”“ Description=”要求内容与正则表达式匹配“ Type=”Microsoft。Wizard.Validation.RegEx“ Name=”RegEx“></ValidatorLibrary> + <DesignerMappings></DesignerConfig>

UDI 向导设计器参考

控件

用于在 UDI 向导设计器中使用的自定义向导页编辑器的控件是 WPF UserControl 实例。 表 69 列出了可用于创建自定义向导页编辑器的控件。

表 69. 可用于创建自定义向导页编辑器的控件

控制 说明
CollectionTControl 此控件用于编辑存储在 Page 元素中的 Data 元素中的数据。
FieldElementControl 此控件用于编辑字段,该字段通常链接到 .xaml 页面上的 TextBox 控件。
SetterControl 此控件用于修改 UDI 向导配置文件中 setter 元素的值。

CollectionTControl

此控件提供了许多用于编辑数据的功能。 了解如何使用此控件的最佳方法是查看示例,该示例显示如何在页面的 Data 元素下编辑数据。 具体而言,此示例演示如何在此控件中添加、删除和编辑项。

FieldElementControl

使用此控件编辑字段,该字段通常链接到 .xaml 页面上的 TextBox 控件。

示例

来自 .xaml 文件的以下摘录说明了如何使用 FieldElementControl 使用子 TextBox 控件在向导页上配置字段的默认值:

<Controls:FieldElementControl  
Width="450"  
Margin="0,5"  
FieldData="{Binding DataContext.Location, ElementName=ControlRoot}"  
HeaderText="Location Combo Box"  
InstructionText="Here you can configure the behavior of the location combo box."  
HideValidationTab="True">  

<TextBox Text="{Binding FieldData.DefaultValue,  
 UpdateSourceTrigger=PropertyChanged,  
 Mode=TwoWay}"/>  
</Controls:FieldElementControl>  
属性
FieldData

此字符串属性包含用于将 FieldElementControl 连接到字段的基础 XML 的信息。 与页面编辑器接口的 属性建立连接。 .xaml 文件中的以下摘录说明了 FieldData 属性的用法:

FieldData="{Binding DataContext.Location, ElementName=ControlRoot}"  

在此摘录中,页面编辑器接口称为 ControlRoot ,并在 ElementName 参数中指定。 对 ControlRoot 页面编辑器接口的 DataContext.Location 属性执行绑定。 DataContext 是指向 UDI 向导配置文件中的 Page 元素的视图模型。 Location 是视图的一个属性,返回可能位置的列表,由 UDI 向导配置文件中的 Data 元素定义。 每个位置由 UDI 向导配置文件中的 DataItem 元素定义。

HeaderText

此字符串属性允许指定 FieldElementControl 控件的标头。 标头充当控件的标题,其格式设置为紧挨在控件上方显示的粗体橙色文本。

InstructionText

使用此字符串属性可为 FieldElementControl 控件指定信息性文本。 通常,文本用于提供字段的简要说明,并说明配置字段如何影响相应的向导页。

HideEnableButton

此布尔属性允许你控制按钮的可见性,该按钮在“ 已解锁 ”和“ 已锁定 ”之间更改状态 (启用或禁用) 。 如果设置为:

  • True,按钮不可见

  • False,按钮可见 (这是默认值。)

HideDefaultTab

使用此布尔属性可以控制包含用于设置默认值的控件的节的可见性。 虽然 属性引用选项卡,但 FieldElementControl 上没有选项卡,而是一个可以隐藏的部分。 如果设置为:

  • True,部分不可见

  • False,部分可见 (这是默认值。)

HideBorder

使用此布尔属性可以控制字段控件周围边框的可见性。 如果设置为:

  • True,边框不可见

  • False,边框可见 (这是默认值。)

HideImage

使用此布尔属性可以控制 FieldImageSource 属性配置的图像的可见性。 如果设置为:

  • True,图像不可见

  • False,图像可见 (这是默认值。)

HideValidationTab

使用此布尔属性可以控制管理验证程序列表的部分的可见性。 虽然 属性引用选项卡,但 FieldElementControl 上没有选项卡,而是一个可以隐藏的部分。 如果设置为:

  • True,部分不可见

  • False,部分可见 (这是默认值。)

HideSummaryTab

使用此布尔属性可以控制在其中配置字段摘要标题的部分的可见性。 字段中的标题和相应值显示在阶段流中的 SummaryPage 向导页类型上。 虽然 属性引用选项卡,但 FieldElementControl 上没有选项卡,而是一个可以隐藏的部分。 如果设置为:

  • True,部分不可见

  • False,部分可见 (这是默认值。)

HideTaskSequenceTab

通过此布尔属性,可以控制配置与 字段对应的任务序列变量的部分的可见性。 虽然 属性引用选项卡,但 FieldElementControl 上没有选项卡,而是一个可以隐藏的部分。 如果设置为:

  • True,部分不可见

  • False,部分可见 (这是默认值。)

SetterControl

使用此控件修改 UDI 向导配置文件中 Setter 元素的值。 此控件包含用于修改 setter 元素的值的子控件。

示例

来自 .xaml 文件的以下摘录说明了如何使用 SetterControl 使用子 TextBox 控件修改名为 KeyLocationSetter 的 Setter 元素。

<Controls:SetterControl Margin="5"  
        Width="450"  
        HeaderText="Title text"  
        SetterData="{Binding KeyLocationSetter}"   
        InstructionText="What this means..."  
        HorizontalAlignment="Left">  

    <TextBox  
                   Margin="0,3"  
                   Text="{Binding SetterData.SetterValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  
    />  

</Controls:SetterControl>  
属性
SetterData

需要将此绑定到连接到资源库的视图或视图模型的属性。 这样做类似于绑定到字段的方式,如 FieldElementControl 中所述。

HeaderText

此属性允许设置将出现在控件标头中的文本。 将此属性视为控件的标题;默认情况下,它显示为加粗的橙色文本。

InstructionText

将此属性设置为要显示在标头下方的文本,通常是指示自定义编辑器用户何时以及为何要修改字段行为的说明文本。

接口

表 70 列出了可用于创建自定义向导页编辑器的接口。

表 70. 可用于创建自定义向导页编辑器的接口

接口 说明
IDataService 使用此接口将字段连接到 UDI 向导配置文件中的数据元素。
IMessageBoxService 此接口提供对可用于显示消息框的方法的访问。

IDataService

此接口包含多个属性和方法,但只需要一个属性。 该属性是此处记录的唯一属性。

可以使用依赖项注入来获取指向此接口的指针,并使用类中的类似代码:

[Dependency]  
public IDataService DataService { get; set; }  
属性

表 71 列出了 IDataService 接口的属性。

表 71. IDataService 接口的属性

接口 说明
CurrentPage 此属性提供对 UDI 向导配置文件中正在编辑的当前页上下文下的 XML 元素、特性和值的访问权限
CurrentPage
XElement CurrentPage { get; set; }  

此属性提供对当前页的 XML 的访问。 切勿设置此属性,但可以随意修改页面的 XML。 示例页编辑器显示了修改 XML 的示例。 主要在具有自定义数据时使用此属性。 对于字段和属性 (资源库) ,可以使用预生成控件来处理所有详细信息。

IMessageBoxService

此接口提供对可用于显示消息框的方法的访问。 你可能想知道为什么需要一个界面来显示消息框。 现实情况是,你不会:Microsoft在代码中使用此接口,因为它有助于编写设计器页面的自动测试。

但是,使用这些方法确实提供了一个有用的好处:对话框始终将“所有者”设置为 UDI 向导,这可确保对话框与主窗口正确分组。

可以使用依赖项注入来获取指向此接口的指针,并使用类中的类似代码:

[Dependency]  
public IMessageBoxService MessageBoxes { get; set; }  
方法

表 72 列出了 IMessageBoxService 接口的方法。

表 72. IMessageBoxService 接口的方法

方法 说明
ShowMessageBox 此重载方法用于显示包含以下成员的消息框:

- ShowMessageBox (字符串消息、字符串标题、MessageBoxImage 图标)
- ShowMessageBox (字符串消息、字符串标题、MessageBoxButton 按钮、MessageBoxImage 图标)
- ShowMessageBox (异常)
ShowDialogWindow 使用此方法可创建新对话框。
ShowWizardWindow 使用此方法可在包含用于导航的“ 下一步 ”和“ 后退 ”按钮的对话框中显示自定义编辑器。
ShowMessageBox

此方法显示一个消息框,该消息框是自定义向导页编辑器的子级。 此成员已重载:表 73 包含成员列表和每个成员的简要说明。 有关每个成员 (包括语法、用法和示例) 的完整信息,请参阅对应于每个成员的部分。

表 73. ShowMessagBox 方法的重载成员

成员 说明
ShowMessageBox (字符串消息、字符串标题、MessageBoxImage 图标) 显示带有图标和 “确定” 按钮的消息框
ShowMessageBox (字符串消息、字符串标题、MessageBoxButton 按钮、MessageBoxImage 图标) 显示带有图标和不同可能按钮组合的消息框
ShowMessageBox (异常) 显示一个消息框,该消息框提供有关异常的信息并具有 “确定” 按钮
ShowMessageBox (字符串消息、字符串标题、MessageBoxImage 图标)
void ShowMessageBox(String message, String caption, MessageBoxImage icon);  

此方法显示带有 “确定” 按钮的消息框。 请参阅表 74。

表 74. ShowMessageBox (String 消息的参数、字符串标题、MessageBoxImage 图标) 方法

参数 说明
邮件 在消息框的内容区域中显示的消息
caption 要显示在对话框标题栏中的文本
icon 在消息框中显示的图标类型
ShowMessageBox (字符串消息、字符串标题、MessageBoxButton 按钮、MessageBoxImage 图标)
MessageBoxResult ShowMessageBox(string message, string caption, MessageBoxButton button, MessageBoxImage icon);  

此方法显示一个消息框,其中包含要显示的按钮集,并报告单击了哪个按钮。 请参阅表 75。

表 75. ShowMessageBox (字符串消息、字符串标题、MessageBoxButton 按钮、MessageBoxImage 图标) 方法的参数

参数 说明
邮件 在消息框的内容区域中显示的消息
caption 要显示在对话框标题栏中的文本
button 要显示的按钮
icon 在消息框中显示的图标类型
ShowMessageBox (异常)
void ShowMessageBox(Exception exception);  

此方法显示一个消息框,用于报告有关异常的信息。 此消息框有一个 “确定” 按钮。 请参阅表 76。

表 76. ShowMessageBox (异常) 方法的参数

参数 说明
例外 要报告的异常 (对话框使用 异常。消息 作为 contents.)
ShowDialogWindow
void ShowDialogWindow(Type viewType, DialogInteraction dialogPayload);  

此方法创建一个新对话框,其内容是 你在 viewType 参数中提供的文本。 UDI 设计器创建此类型的新实例,并将其包装在具有 “确定” 和“ 取消 ”按钮的对话框中。

使用 dialogPayload 参数将数据传递给控件。 SDK 目录中的 SampleEditor 解决方案提供了如何使用此功能的示例。

ShowWizardWindow
void ShowWizardWindow(Type viewType, DialogInteraction dialogPayload);  

此方法允许在包含导航的“ 下一步 ”和“ 后退 ”按钮的对话框中显示自定义编辑器。 Microsoft尚未提供有关如何使用此方法的示例。

UDI 向导配置文件架构参考

此文件由 UDI 向导使用,并由 UDI 向导设计器配置。 此文件用于配置:

  • UDI 向导中显示的向导页

  • UDI 向导中向导页的顺序

  • 每个向导页上字段的设置

  • UDI 向导设计器中的可用阶段组

  • UDI 向导设计器中每个部署向导中的可用阶段

    77 列出了 UDI 向导配置文件中的元素及其说明。 Wizard 元素是此引用的根节点。

表 77. UDI 向导配置文件中的元素及其说明

元素名 说明
Data Page 元素中的单个 DataItem 元素进行分组,由 Name 属性命名。
DataItem Page 元素中的单个 Setter 元素进行分组。 可以通过在 DataItem 元素中包含一个或多个 Data 元素来创建分层数据。 每个 DataItem 元素表示单个项。 例如,可用驱动器的列表可能有 一个 DataItem 作为显示名称,另一个 DataItem 元素表示相应的驱动器号。
默认 为父 FieldRadioGroup 元素中指定的字段指定默认值。 默认值设置为此元素括起来的值。
Dll 指定要由 UDI 向导和 UDI 向导设计器加载和引用的 DLL。
Dll 对单个 DLL 元素进行分组。
错误 指定任务可以返回的可能错误代码。 错误代码的值由任务的 HRESULT 返回,并被此元素捕获,以提供更具体的错误信息。
ExitCode 指定任务的可能退出代码。 退出代码是任务预期的返回代码。 为每个可能的退出代码创建 ExitCode 元素。 否则,可以在 Value 属性中指定星号 (*) 来处理其他 ExitCode 元素中未列出的返回代码。
ExitCodes Task 元素或 Error 元素的一组 ExitCodeError 元素进行分组。
字段 指定 Page 元素中用于通过 XML 提供自定义项的控件的实例。 并非所有控件都允许使用 XML 进行自定义,仅允许使用 Field 元素的控件。
Fields Page 元素中的单个 Field 元素进行分组。
文件 使用 Microsoft 指定文件复制操作的源和目标。Wizard.CopyFilesTask 任务类型。 可以包含单独的 File 元素,以在单个任务中复制多个文件。
Page 指定页面的实例,并包括该页的所有配置设置。
PageRef 指定对 StageGroup阶段内页面实例的引用。
Pages 对各个 Page 元素进行分组。
RadioGroup 指定 Field 元素中的一组单选按钮。
StageGroup 指定一个或多个阶段的组。
StageGroups 在 UDI 向导配置文件中对一组阶段组进行分组。
Setter 为在 Property 属性中命名的属性指定 值的属性设置
"阶段" 指定 StageGroup 中的阶段,并包含一个或多个 PageRef 元素。
样式 对配置 UDI 向导外观的各个 setter 元素进行分组,包括向导顶部显示的标题和 UDI 向导上显示的横幅图像。
任务 指定要在父 Page 元素中指定的页面上运行的任务。
Tasks Page 元素的一组任务进行分组。
验证 在父 Field 元素中指定的字段控件指定一个验证程序。
Wizard 指定所有其他元素的根。

Data

此元素对 Page 元素中的单个 DataItem 元素进行分组,由 Name 属性命名。

元素信息

表 78 提供了有关 Data 元素的信息。

表 78. 数据元素信息

属性
出现次数 每个 Page 元素中的零个或多个 (此元素是可选的。)
父元素 PageDataItem
目录 DataItemSetter
元素属性

表 79 列出了 Data 元素的属性,并提供了每个属性的说明。

表 79. 数据元素的属性和相应值

属性 说明
名称 指定 Data 元素的名称
备注

Name 属性允许代码检索一组特定的数据。

示例

无。

DataItem

此元素对 Page 元素中的单个 Setter 元素进行分组。 可以通过在 DataItem 元素中包含一个或多个 Data 元素来创建分层数据。 每个 DataItem 元素表示单个项。 例如,可用驱动器的列表可能有 一个 DataItem 作为显示名称,另一个 DataItem 元素表示相应的驱动器号。

元素信息

表 80 提供了有关 DataItem 元素的信息。

表 80. DataItem 元素信息

属性
出现次数 每个 Data 元素中的零个或多个 (此元素是可选的。)
父元素 Data
目录 DataSetter
元素属性

此元素没有属性。

备注

无。

示例

无。

默认值

此元素指定父 Field 或 RadioGroup 元素中指定的字段的默认值。 默认值设置为此元素括号的值。

元素信息

表 81 提供了有关 Default 元素的信息。

表 81. 默认元素信息

属性
出现次数 FieldRadioGroup 元素中的零个或多个 (此元素是可选的。)
父元素 FieldRadioGroup
目录 可以是任何格式正确的 XML 内容,但通常是标准文本
元素属性

此元素没有属性。

备注

无。

示例

在以下示例中, TimeZone 字段的默认值设置为“太平洋标准时间”:

<Field Name="TimeZone" Enabled="true" VarName="OSDTimeZone" Summary="Time Zone:">  
  <Default>Pacific Standard Time</Default>  

Dll

此元素指定要加载和引用的 UDI 向导和 UDI 向导设计器的 DLL。

元素信息

表 82 提供了有关 DLL 元素的信息。

表 82. DLL 元素信息

属性
出现次数 DLL 元素中的一个或多个
父元素 Dll
目录 此元素不允许包含任何内容
元素属性

表 83 列出了 DLL 元素的属性,并提供了每个属性的说明。

表 83. DLL 元素的属性和相应值

属性 说明
名称 指定要引用的 UDI 向导和 UDI 向导设计器的 DLL 的名称
备注

无。

示例
<DLLs>  
  <DLL Name="OSDRefreshWizard.dll" />   
  <DLL Name="SharedPages.dll" />  
</DLLs>  

Dll

此元素对各个 DLL 元素进行分组。

元素信息

表 84 提供了有关 DLL 元素的信息。

表 84. DLL 元素信息

属性
出现次数 一个
父元素 Wizard
目录 Dll
元素属性

此元素没有属性。

备注

无。

示例
<DLLs>  
   <DLL Name="OSDRefreshWizard.dll" />  
   <DLL Name="SharedPages.dll" />   
</DLLs>  

Error

此元素指定任务可以返回的可能错误代码。 错误代码的值由任务的 HRESULT 返回并捕获,以提供更具体的错误信息。

元素信息

表 85 提供了有关 Error 元素的信息。

表 85. Error 元素信息

属性
出现次数 每个 ExitCode 元素中的零个或多个 (此元素是可选的。)
父元素 ExitCodes
目录 任何格式正确的 XML 内容
元素属性

表 86 列出了 Error 元素的属性,并提供了每个属性的说明。

表 86. Error 元素信息

属性 说明
状态 指定遇到错误的任务的返回状态。 通常,此属性的值设置为 Error。 此值显示在 UDI 向导的向导页上的 “状态 ”列中。
Text 指定有关任务遇到的错误条件的描述性文本。
类型 指定此元素是表示错误、警告还是成功。 Type 中指定的值在 ExitCodes 元素中必须是唯一的。 以下是此元素的有效值:

- 0.元素表示成功。
- 1. 元素表示警告。
- -1。 元素表示错误。
指定任务作为数值返回的代码的值。 指定星号的值 (*) 指示其他 Error 元素中未列出的返回代码的默认元素。
备注

无。

示例

无。

ExitCode

此元素指定任务的可能退出代码。 退出代码是任务预期的返回代码。 为每个可能的退出代码创建 ExitCode 元素。 否则,可以在 Value 属性中指定星号 (*) 来处理其他 ExitCode 元素中未列出的返回代码。

元素信息

表 87 提供了有关 ExitCode 元素的信息。

表 87. ExitCode 元素信息

属性
出现次数 每个 ExitCodes 元素中的零个或多个 (此元素是可选的。)
父元素 ExitCodes
目录 至少一个 ExitCode 元素和零个或多个 Error 元素
元素属性

表 88 列出了 ExitCode 元素的属性,并提供了每个属性的说明。

表 88. ExitCode 元素的属性和相应值

属性 说明
状态 指定任务的返回状态。 此属性的值显示在 UDI 向导中相应向导页上的 “状态 ”列中。 可以为此属性使用对任务有意义的任何值。 下面是用于此属性的典型值:

-成功
-警告
-错误
Text 指定有关任务存在代码的描述性文本。
类型 指定此元素是表示错误、警告还是成功。 类型中指定的值在 ExitCodes 元素中必须是唯一的。 以下是此元素的有效值:

- 0. 元素表示成功。
- 1. 元素表示警告。
- -1。 元素表示错误。
指定任务作为数值返回的代码的值。 指定星号 (*) 指示其他 ExitCode 元素中未列出的返回代码的默认元素。
备注

无。

示例

无。

ExitCodes

此元素对 TaskError 元素的一组 ExitCodeError 元素进行分组。

元素信息

表 89 提供了有关 ExitCodes 元素的信息。

表 89. ExitCodes 元素信息

属性
出现次数 每个 Task 元素中各一个
父元素 任务
目录 ErrorExitCode
元素属性

此元素没有属性。

备注

无。

示例

无。

字段

此元素指定用于通过 XML 提供自定义项的 Page 元素中的控件实例。 并非所有控件都允许使用 XML 进行自定义,仅允许使用 Field 元素的控件。

元素信息

表 90 提供了有关 Field 元素的信息。

表 90. Field 元素信息

属性
出现次数 每个 Field 元素中的零个或多个 (此元素是可选的。)
父元素 Fields
目录 默认值验证器
元素属性

表 91 列出了 Field 元素的属性,并提供了每个属性的说明。

表 91. Field 元素的属性和相应值

属性 说明
Enabled 指定是否为用户输入启用字段 (属性可设置为 True 或 False。)
名称 指定字段的名称
摘要 指定此字段设置的值在 “摘要 ”向导页上显示的描述性文本
VarName 指定使用父 Field 元素中的 字段读取或配置的任务序列变量名称
备注

此元素可以包含零个或多个 Default 元素和零个或多个 验证器 元素。

示例

无。

字段

此元素对 Page 元素中的单个 Field 元素进行分组。

元素信息

表 92 提供了有关 Fields 元素的信息。

表 92. Fields 元素信息

属性
出现次数 每个 Page 元素中的零个或多个 (此元素是可选的。)
父元素 Page
目录 FieldRadioGroup
元素属性

此元素没有属性。

备注

无。

示例

无。

文件

此元素使用 Microsoft 指定文件复制操作的源和目标。Wizard.CopyFilesTask 任务类型。 可以包含单独的 File 元素,以在单个任务中复制多个文件。

元素信息

表 93 提供了有关 File 元素的信息。

表 93. 文件元素信息

属性
出现次数 任务类型为Microsoft的每个任务都有一个或多个。Wizard.CopyFilesTask
父元素 任务
目录
元素属性

表 94 列出了 File 元素的属性,并提供了每个属性的说明。

表 94. File 元素的属性和相应值

属性 说明
Dest 指定 Source 属性中指定的文件的目标文件夹的完全限定或相对路径。 允许将环境变量作为路径的一部分。
Source 指定Microsoft源文件的完全限定路径或相对路径。Wizard.CopyFilesTask 任务类型副本。 此属性支持通配符,以便可以使用单个 File 元素复制多个 文件 。 允许将环境变量作为路径的一部分。
备注

无。

示例

无。

Page

此元素指定页面的实例,并包括该页的所有配置设置。

元素信息

表 95 提供了有关 Page 元素的信息。

表 95. Page 元素信息

属性
出现次数 每个 Pages 元素中的一个或多个
父元素 Pages
目录 数据字段资源库任务
元素属性

表 96 列出了 Page 元素的属性,并提供了每个属性的说明。

表 96. Page 元素的属性和相应值

属性 说明
DisplayName 指定 UDI 向导设计器中显示的向导页的用户友好名称。 此名称通常比 Name 属性更具描述性。
名称 指定 UDI 向导设计器中显示的向导页的名称。
类型 指定与 DLL 中的特定向导页直接相关的向导页的类型。
备注

无。

示例

无。

PageRef

此元素指定对 StageGroup阶段内页面实例的引用。

元素信息

表 97 提供了有关 PageRef 元素的信息。

表 97. PageRef 元素信息

属性
出现次数 Stage 元素中的一个或多个
父元素 "阶段"
目录
元素属性

表 98 列出了 PageRef 元素的属性,并提供了它的说明。

表 98. PageRef 元素的属性和相应值

属性 说明
Page 指定 StageGroup阶段中页面的实例。 将此值设置为 Page 元素的 Name 属性。
备注

无。

示例

无。

页面

此元素对各个 Page 元素进行分组。

元素信息

表 99 提供了有关 Pages 元素的信息。

表 99. Pages 元素信息

属性
出现次数 一个
父元素 Wizard
目录 Page
元素属性

此元素没有属性。

备注

无。

示例
<Pages>  
   + <Page Name="WelcomePage" DisplayName="Welcome" Type="Microsoft.SharedPages.WelcomePage">  
   + <Page Name="ConfigScanPage" DisplayName="Deployment Readiness" Type="Microsoft.OSDRefresh.ConfigScanPage">  
   + <Page Name="ConfigScanBareMetal" DisplayName="Deployment Readiness" Type="Microsoft.OSDRefresh.ConfigScanPage">  
   + <Page Name="RebootPage" DisplayName="Reboot" Type="Microsoft.OSDRefresh.RebootPage">  
   + <Page Name="WelcomePageReplace" DisplayName="Welcome" Type="Microsoft.SharedPages.WelcomePage">  
   + <Page Name="VolumePage" DisplayName="Volume" Type="Microsoft.OSDRefresh.VolumePage">  
   + <Page Name="UserRestorePage" DisplayName="Select Target" Type="Microsoft.OSDRefresh.UserStatePage">  
   + <Page Name="ComputerPage" DisplayName="New Computer Details" Type="Microsoft.OSDRefresh.ComputerPage">  
   + <Page Name="AdminAccounts" DisplayName="Administrator Password" Type="Microsoft.SharedPages.AdminAccountsPage">  
   + <Page Name="UDAPage" DisplayName="User Device Affinity" Type="Microsoft.OSDRefresh.UDAPage">  
   + <Page Name="LanguagePage" DisplayName="Language" Type="Microsoft.OSDRefresh.LanguagePage">  
   + <Page Name="ApplicationPage" DisplayName="Install Programs" Type="Microsoft.OSDRefresh.ApplicationPage">  
     <Page Name="SummaryPage" DisplayName="Summary" Type="Microsoft.Shared.SummaryPage" />   
   + <Page Name="UserCapturePageOldPC" DisplayName="Select Target" Type="Microsoft.OSDRefresh.UserStatePage">  
   + <Page Name="ProgressPage" DisplayName="Capture Data" Type="Microsoft.OSDRefresh.ProgressPage">  
   + <Page Name="RebootAfterCapture" DisplayName="Reboot" Type="Microsoft.OSDRefresh.RebootPage">  
</Pages>  

RadioGroup

此元素在 Field 元素中使用 指定一组单选按钮。

元素信息

表 100 提供了有关 RadioGroup 元素的信息。

表 100. RadioGroup 元素信息

属性
出现次数 Fields 元素中的零个或多个 (此元素是可选的。)
父元素 Fields
目录 默认
元素属性

表 101 列出了 RadioGroup 元素的属性,并提供了每个属性的说明。

表 101. RadioGroup 元素的属性和相应值

属性 说明
Locked 指定是否为用户输入启用单选按钮组。 属性可设置为:

- True。 指定禁用单选按钮,并且用户无法选择组中的单选按钮。
- False。 指定启用单选按钮,并且用户可以选择组中的单选按钮。
名称 指定单选选项组的名称。
备注

无。

示例

无。

StageGroup

此元素指定部署阶段组。

元素信息

表 102 提供了有关 StageGroup 元素的信息。

表 102. StageGroup 元素信息

属性
出现次数 StageGroups 元素中的一个或多个
父元素 StageGroups
目录 "阶段"
元素属性

表 103 列出了 StageGroup 元素的属性和属性的说明。

表 103. StageGroup 元素的属性和相应值

属性 说明
DisplayName 指定 UDI 向导设计器中显示的阶段组的用户友好名称。 此名称通常比 Name 属性更具描述性。
备注

无。

示例

无。

StageGroups

此元素对 UDI 向导配置文件中的一组阶段组进行分组。

元素信息

表 104 提供了有关 StageGroups 元素的信息。

表 104. StageGroups 元素信息

属性
出现次数 Wizard 元素中的零个或 1 个
父元素 Wizard
目录 StageGroup
元素属性

此元素没有属性。

备注

无。

示例

无。

Setter

此元素为 Property 属性中命名的属性的值指定 属性 设置。

元素信息

表 105 提供了有关 Setter 元素的信息。

表 105. Setter 元素信息

属性
出现次数 每个父元素中的零个或多个 (此元素是可选的。)
父元素 DataDataItemPageStyleTaskValidator
目录 包含 Property 属性中的字符串值
元素属性

表 106 列出了 Setter 元素的属性,并提供了它的说明。

表 106. Setter 元素的属性和相应值

属性 说明
属性 指定要设置的属性名称。 属性名称设置为此属性括号的值。
备注

无。

示例

无。

阶段

此元素指定 StageGroup 中的阶段,并包含一个或多个 PageRef 元素。

元素信息

表 107 提供了有关 Stage 元素的信息。

表 107. Stage 元素信息

属性
出现次数 StageGroup 元素中的一个或多个
父元素 StageGroup
目录 PageRef
元素属性

表 108 列出了 Stage 元素的属性,并提供了每个属性的说明。

表 108. Stage 元素的属性和相应值

属性 说明
DisplayName 指定 UDI 向导设计器中显示的向导页的用户友好名称。 此名称通常比 Name 属性更具描述性。
名称 指定阶段的名称。 使用 /stage: name 命令行参数启动 UDI 向导时使用此元素的值。
备注

无。

示例

无。

样式

此元素对配置 UDI 向导外观的单个 Setter 元素进行分组,包括向导顶部显示的标题和 UDI 向导上显示的横幅图像。

元素信息

表 109 提供了有关 Style 元素的信息。

表 109. Style 元素信息

属性
出现次数 一个
父元素 Wizard
目录 Setter
元素属性

此元素没有属性。

备注

无。

示例
<Style>  
  <Setter Property="bannerFilename">UDI_Wizard_Banner.bmp</Setter>   
  <Setter Property="title">Operating System Deployment (OSD) Refresh Wizard</Setter>   
</Style>  

任务

此元素指定要在父 Page 元素中指定的页面上运行的任务。

元素信息

表 110 提供了有关 Task 元素的信息。

表 110. 任务元素信息

属性
出现次数 Tasks 元素中的一个或多个
父元素 Tasks
目录 ExitCodes文件Setter
元素属性

表 111 列出了 Task 元素的属性,并提供了每个属性的说明。

表 111. Task 元素的属性和相应值

属性 说明
DependsOn 指定任务是否依赖于另一个任务。 此属性的值设置为另一个 Task 元素的 Name 属性。 注意: 无法使用 UDI 向导设计器配置此属性。 但是,可以通过直接修改 .xml 文件手动将此属性添加到 Task 元素。
DisplayName 指定 UDI 向导设计器中显示的任务的用户友好名称。 此名称通常比 Name 属性更具描述性。
名称 指定任务的名称。 此名称必须唯一。
类型 指定要运行的任务的任务类型,该类型在包含任务的 DLL 中定义。
备注

无。

示例

无。

任务

此元素对 Page 元素的一组任务进行分组。

元素信息

表 112 提供了有关 Tasks 元素的信息。

表 112. Tasks 元素信息

属性
出现次数 每个 Page 元素中的零个或一个, (此元素是可选的。)
父元素 Page
目录 任务
元素属性

表 113 列出了 Tasks 元素的属性,并提供了每个属性的说明。

表 113. Tasks 元素的属性和相应值

属性 说明
NameTitle 指定显示在相应向导页中包含任务名称的列顶部的标题。
StatusTitle 指定显示在相应向导页中包含任务状态的列顶部的标题。
备注

无。

示例

无。

验证

此元素指定在父 Field 元素中指定的字段控件的验证程序。

元素信息

表 114 提供了有关 验证器 元素的信息。

表 114. 验证器元素信息

属性
出现次数 Field 元素中的零个或一个
父元素 字段
目录 Setter
元素属性

表 115 列出了 Validator 元素的属性,并提供了它的说明。

表 115. 验证器元素的属性和相应值

属性 说明
类型 指定验证程序的类型,该类型在包含验证器的 DLL 中定义
备注

无。

示例

无。

向导

此元素指定所有其他元素的根。

元素信息

表 116 提供了有关 Wizard 元素的信息。

表 116. Wizard 元素信息

属性
出现次数 一个
父元素
目录 DLL页面StageGroups样式
元素属性

此元素没有属性。

备注

无。

示例
<Wizard>  
   + <DLLs>  
   + <Style>  
   + <Pages>  
   + <StageGroups>  
</Wizard>