代码示例:辅助安装程序中的 Finish-Install 操作

注意

通用或移动驱动程序包不支持本部分所述的功能。 请参阅 使用通用 INF 文件

在此示例中,共同安装程序执行以下操作以支持完成安装操作:

  • 当共同安装程序收到 DIF_NEWDEVICEWIZARD_FINISHINSTALL 请求时,它会调用安装程序提供的函数 FinishInstallActionsNeeded 来确定是否有要执行的完成安装操作。 (此示例中未显示 FinishInstallActionsNeeded 函数的代码) 。

    如果 FinishInstallActionsNeeded 返回 TRUE,则共同安装程序将调用 SetupDiGetDeviceInstallParams 来检索设备的设备安装参数,然后调用 SetupDiSetDeviceInstallParams 来设置具有 DI_FLAGSEX_FINISHINSTALL_ACTION 标志的设备SP_DEVINSTALL_PARAMS结构的 FlagsEx 成员。 设置此标志会导致 Windows 向安装此设备所涉及的所有类安装程序、类共同安装程序和设备共同安装程序发送 DIF_FINISHINSTALL_ACTION 请求。 完成所有安装操作(完成安装操作除外)后发送此请求。

  • 当共同安装程序收到DIF_FINISHINSTALL_ACTION请求时,共同安装程序将再次调用 FinishInstallActionsNeeded ,以确定它是否有要执行的完成安装操作,如果是,则执行完成安装操作。 共同安装程序通知用户完成安装操作正在进行,并等待完成安装操作完成,然后返回处理DIF_FINISHINSTALL_ACTION请求。

  • 如果完成安装操作成功,共同安装程序会通知用户完成安装操作成功。

  • 如果完成安装操作需要重启系统才能完成安装操作,则共同安装程序调用 SetupDiGetDeviceInstallParams 来检索设备的设备安装参数,然后调用 SetupDiSetDeviceInstallParams 来设置具有 DI_NEEDREBOOT 标志的设备SP_DEVINSTALL_PARAMS结构的 Flags 成员。 安装程序还会通知用户需要重启系统。

  • 如果完成安装操作失败,并且应在下次枚举设备时再次尝试完成安装操作,则共同安装程序会通知用户这种情况。

    注意从Windows 8完成安装操作仅运行一次。 Windows 不会再次自动运行它,尤其是在下次枚举设备时,因为这不是运行完成安装操作时。

  • 如果完成安装操作失败,并且共同安装程序确定完成安装操作无法成功,则共同安装程序会通知用户这种情况。

  • 默认情况下,如果完成安装操作成功,或者完成安装操作失败,并且共同安装程序确定不应再次尝试完成安装操作,则共同安装程序将返回NO_ERROR以响应DIF_FINISHINSTALL_ACTION请求。 仅当完成安装操作失败并且应在下次在管理员上下文中枚举设备时再次尝试完成安装操作时,共同安装程序才会返回 Win32 错误代码。

    注意从Windows 8完成安装操作仅运行一次。 Windows 不会再次自动运行它,尤其是在下次枚举设备时,因为这不是运行完成安装操作时。

以下共同安装程序代码示例演示了实现完成安装操作的共同安装程序代码的基本结构:

DWORD CALLBACK
SampleCoInstaller(
  IN DI_FUNCTION  InstallFunction,
  IN HDEVINFO  DeviceInfoSet,
  IN PSP_DEVINFO_DATA  DeviceInfoData,
  IN OUT PCOINSTALLER_CONTEXT_DATA  Context
  )
{
  SP_DEVINSTALL_PARAMS DeviceInstallParams;
  DWORD ReturnValue = NO_ERROR; // The default return value

  switch(InstallFunction)
  {
    case DIF_NEWDEVICEWIZARD_FINISHINSTALL:
      //
      // Processing for finish-install wizard pages
      //
      // Processing for finish-install actions
      if (FinishInstallActionsNeeded())
      {
        // Obtain the device install parameters for the device
        // and set the DI_FLAGSEX_FINISHINSTALL_ACTION flag
        DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
        if (SetupDiGetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &DeviceInstallParams))
        {
          DeviceInstallParams.FlagsEx |= DI_FLAGSEX_FINISHINSTALL_ACTION;
          SetupDiSetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &DeviceInstallParams);
        }
      }
      break;

    case DIF_FINISHINSTALL_ACTION:
      if (FinishInstallActionsNeeded())
      {
        //
        // Perform the finish-install actions,
        // notify the user that finish install actions
        // are in progress and wait for
        // the finish-install actions to complete
        //
        // If the finish-install actions succeed, notify the user
        //
        // If the finish install actions require a system restart: 
        // notify the user, call SetupDiGetDeviceInstallParams 
        // to obtain the device install parameters for the device in 
        // DeviceInstallParams, and call SetupDiSetInstallParams to set 
        // the DI_NEEDREBOOT flag in DeviceInstallParams.Flags
        // 
        // If the finish install actions failed, but
        // should be attempted again: clean up,
        // notify the user of the failure, and
        // set ReturnValue to an appropriate Win32 error code
        //
        // If the finish install actions failed and 
        // should not be attempted again: clean up
        // and notify the user of the failure
        //
        // Starting with Windows 8, a finish-install action
        // is only run once. Windows will not automatically
        // run it again, especially not the next time
        // the device is enumerated because that is not when
        // finish-install actions are run.
        //
      }
      break;
  }

  return ReturnValue;
}