SystemUpdateManager 类

定义

SystemUpdateManager 允许以交互方式控制系统更新。

public ref class SystemUpdateManager abstract sealed
/// [Windows.Foundation.Metadata.ContractVersion(Windows.System.SystemManagementContract, 393216)]
/// [Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
/// [Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
class SystemUpdateManager final
[Windows.Foundation.Metadata.ContractVersion(typeof(Windows.System.SystemManagementContract), 393216)]
[Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
[Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
public static class SystemUpdateManager
Public Class SystemUpdateManager
继承
Object Platform::Object IInspectable SystemUpdateManager
属性

Windows 要求

设备系列
Windows 10, version 1809 (在 10.0.17763.0 中引入)
API contract
Windows.System.SystemManagementContract (在 v6.0 中引入)

示例

SystemUpdateManager 示例代码

注解

SystemUpdateFlow

系统更新过程具有以下状态:

  1. 检测。 确定是否有可用的更新包。
  2. 下载。 从服务器下载更新包。
  3. 阶段。 解压缩更新包并暂暂保存更新包,以便稍后提交。
  4. 等待重新启动到更新 OS。 更新 OS 在提交操作系统更改时显示Windows 10 IoT 核心版齿轮。
  5. 提交。 启动到更新 OS,在提交系统更新更改时显示齿轮。
  6. 重新启动到更新的主 OS。 此时,更新过程已完成。

安装更新包包括通过将文件和设置提取到暂存区域,然后提交暂存更改来暂存更新包。 提交阶段开始后,无法在Windows 10 IoT 核心版回滚更新包。 如有必要,可以通过取消更新来丢弃仅暂暂的未提交的更新包。 提交过程一旦启动,就不能中断。

自动更新过程由策略控制。 OEM 可以通过策略管理器(如 MDM)或 DUC (设备更新中心) 来控制策略。

交互式更新进程会话由设备用户控制。 在交互式更新进程会话期间,可能会重写延迟自动更新过程的策略。 例如,当自动更新进程会话被当前策略阻止执行这些操作时,用户可以扫描更新包,并使用交互式进程会话下载它们。 交互式更新过程还可以暂更新包。 暂存更新包解压缩包,并准备要提交的包中的文件和设置。

下载并暂存在更新包后,开发人员可以通过重新启动到更新操作系统并提交更新包来继续交互式更新过程。 更新 OS 是一个非常小的操作系统,其唯一目的是提交更新包。 在Windows 10 IoT 核心版更新操作系统上显示一个带有移动齿轮的屏幕。 重启到更新 OS 可以响应用户输入或作为单一用途设备业务逻辑的一部分。 必须调用 RebootToCompleteInstall 才能继续更新 OS。 打开和关闭电源或使用备用 API 重新启动设备将不起作用。 或者,开发人员可以选择等到当前策略配置的下一个计划的自动更新进程重启窗口,例如, (非活动时段。)

安装之前

在尝试使用 SystemUpdateManager API 之前,应用程序应验证是否存在 SystemManagementContract 6.0。

if (!ApiInformation.IsApiContractPresent("Windows.System.SystemManagementContract", 6, 0))
{
    // SystemUpdateManager was first implemented in SystemManagementContract 6.0
    VisualStateManager.GoToState(this, "NotSupported", false);
    UpdateStateTextBlock.Text = "Windows.System.SystemManagementContract 6.0 not found";
}

接下来,应用程序应确保 SystemUpdateManager 在当前版本的 Windows 上受支持。

else if (!SystemUpdateManager.IsSupported())
{
    // The API must be supported by the current edition of Windows
    // This can also return false if the application doesn't have the systemManagement capability
    VisualStateManager.GoToState(this, "NotSupported", false);
    UpdateStateTextBlock.Text = "System Update not supported (or systemManagement capability missing)";
}

显示系统更新状态

如果存在协定且 API 受支持,则注册状态更改通知:

// Register for state change notifications
SystemUpdateManager.StateChanged += SystemUpdateManager_StateChanged;

private void SystemUpdateManager_StateChanged(object sender, object args)
{
    var action = _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        UpdateVisualState();
    });
}

初始化用户界面:

// Display update information
UpdateStateTextBlock.Text = GetResourceString(SystemUpdateManager.State.ToString());
LastChecked.Text = SystemUpdateManager.LastUpdateCheckTime.ToString("G");
LastInstalled.Text = SystemUpdateManager.LastUpdateInstallTime.ToString("G");

// Attach ViewModel to ListView
UpdateItemsListView.ItemsSource = _items;

// Initialize the visual state
UpdateVisualState();
UpdateFlightRing();

BlockAutoReboot.IsOn = IsAutomaticRebootBlockOn();

UpdateVisualState 示例代码函数执行以下操作:

  1. 汇报状态字段。
  2. 汇报上次更新检查时间。
  3. 汇报 VisualStateManager 状态。
  4. 汇报进度状态的进度栏。
  5. 汇报更新项状态。

代码如下:

private void UpdateVisualState()
{
    // Update the state text
    UpdateStateTextBlock.Text = GetResourceString(SystemUpdateManager.State.ToString());

    // Update the last update check time
    LastChecked.Text = SystemUpdateManager.LastUpdateCheckTime.ToString("G");

    // Change the VisualStateManager state based on the current SystemUpdateManagerState
    var state = SystemUpdateManager.State;
    Debug.WriteLine($"State={state}");
    switch (state)
    {
        case SystemUpdateManagerState.Idle:
        case SystemUpdateManagerState.Detecting:
        case SystemUpdateManagerState.Downloading:
        case SystemUpdateManagerState.Installing:
        case SystemUpdateManagerState.RebootRequired:
            VisualStateManager.GoToState(this, SystemUpdateManager.State.ToString(), false);
            break;

        case SystemUpdateManagerState.AttentionRequired:
            AttentionRequiredTextBlock.Text = GetResourceString(SystemUpdateManager.AttentionRequiredReason.ToString());
            VisualStateManager.GoToState(this, "AttentionRequired", false);
            break;

        default:
            VisualStateManager.GoToState(this, "UnknownState", false);
            break;
    }

    // Update progress for states with progress
    switch (SystemUpdateManager.State)
    {
        case SystemUpdateManagerState.Downloading:
            Debug.WriteLine($"Downloading={SystemUpdateManager.DownloadProgress}");
            SessionDownloadProgressBar.Value = SystemUpdateManager.DownloadProgress;
            break;
        case SystemUpdateManagerState.Installing:
            Debug.WriteLine($"Installing={SystemUpdateManager.InstallProgress}");
            SessionDownloadProgressBar.Value = SystemUpdateManager.DownloadProgress;
            SessionInstallProgressBar.Value = SystemUpdateManager.InstallProgress;
            break;
    }

    // Update progress items
    switch (SystemUpdateManager.State)
    {
        case SystemUpdateManagerState.Downloading:
        case SystemUpdateManagerState.Installing:
            foreach (var updateItem in SystemUpdateManager.GetUpdateItems())
            {
                var viewModelItem = _items.Where(x => x.Id == updateItem.Id).FirstOrDefault();
                if (viewModelItem != null)
                {
                    viewModelItem.Update(updateItem);
                }
                else
                {
                    _items.Add(new UpdateItemViewModel(updateItem));
                }
            }
            break;
    }
}

安装系统更新

如果设备所有者配置了自动更新进程策略,以便控制下载开始的时间,或者他们选择允许客户以交互方式启动更新过程,则调用 SystemUpdateManager.StartInstall 将检查更新包并下载更新包(如果存在)。 这是一种以异步方式运行但立即返回的即用即用方法。

可以通过 StateChanged 事件和 State 属性跟踪更新过程的进度。 如果下载已在进行中,则调用将立即返回,而不会出错。 如果需要用户注意才能继续,则状态设置为 AttentionRequired ,并将 AttentionRequiredReason 设置为 。 如果发生不可恢复的错误,则状态设置为 ExtendedError,并设置 ExtendedError 属性。

若要开始更新,请调用 SystemUpdateManager.StartInstall。 如果参数为 SystemUpdateStartInstallAction.UpToReboot ,则安装将继续,直到需要重新启动。 如果参数为 SystemUpdateStartInstallAction.AllowReboot ,则安装将继续,并在策略允许后立即重新启动。

private void CheckForUpdates_Click(object sender, RoutedEventArgs e)
{
    if (SystemUpdateManager.State == SystemUpdateManagerState.Idle)
    {
        SystemUpdateManager.StartInstall(SystemUpdateStartInstallAction.UpToReboot);
    }
}

若要提交系统更新安装,有时需要重新启动。 在这种情况下 ,SystemUpdateManager.State 将等于 SystemUpdateManagerState.RebootRequired。 请注意,正常重启无法完成此状态下的更改。 必须调用 SystemUpdateManager.RebootToCompleteInstall 或等待系统更新窗口期间自动计划的重新启动发生, (用户活动时段) 以外的时间。

private void RebootNow_Click(object sender, RoutedEventArgs e)
{
    if (SystemUpdateManager.State == SystemUpdateManagerState.RebootRequired)
    {
        SystemUpdateManager.RebootToCompleteInstall();
    }
}

管理用户使用小时数:

private void ChangeActiveHours_Click(object sender, RoutedEventArgs e)
{
    StartTime.Time = SystemUpdateManager.UserActiveHoursStart;
    EndTime.Time = SystemUpdateManager.UserActiveHoursEnd;
    ActiveHoursErrorText.Visibility = Visibility.Collapsed;
    ActiveHoursPopup.IsOpen = true;
}

private void SaveActiveHours_Click(object sender, RoutedEventArgs e)
{
    bool succeeded = SystemUpdateManager.TrySetUserActiveHours(StartTime.Time, EndTime.Time);
    if (succeeded)
    {
        ActiveHoursPopup.IsOpen = false;
    }
    else
    {
        // Active hours not set display error message
        string format = GetResourceString("ActiveHoursErrorFormat");
        ActiveHoursErrorText.Text = String.Format(format, SystemUpdateManager.UserActiveHoursMax);
        ActiveHoursErrorText.Visibility = Visibility.Visible;
    }
}

获取上次系统更新错误

如果在安装系统更新期间发生错误,则将设置 SystemUpdateManager.LastErrorInfo 。 下面是显示最后一个错误信息的示例:

var info = SystemUpdateManager.LastErrorInfo;
if (SystemUpdateManager.LastErrorInfo.ExtendedError == null)
{
    NoErrorText.Visibility = Visibility.Visible;
    LastErrorInfoPanel.Visibility = Visibility.Collapsed;
}
else
{
    NoErrorText.Visibility = Visibility.Collapsed;
    LastErrorInfoPanel.Visibility = Visibility.Visible;
    ErrorStateTextBlock.Text = GetResourceString(info.State.ToString());
    HResultTextBlock.Text = (info.ExtendedError == null) ? "No Error Data" : info.ExtendedError.Message;
    IsInteractiveTextBlock.Text = GetResourceString(info.IsInteractive ? "Yes" : "No");
}

系统更新外部测试版圈

外部测试环可以是空的、金丝雀的、自承载的,也可以是用户定义的。 如果值为空,则在 UI 中选择“无”。 否则,如果它不是 Canary 或 Selfhost,则假定环是用户定义的,并将其保存到 UI 列表。

private void UpdateFlightRing()
{
    var ring = Windows.System.Update.SystemUpdateManager.GetFlightRing();
    for (int i = 0; i < FlightRingCombo.Items.Count(); i++)
    {
        if (ring == FlightRingCombo.Items[i] as string)
        {
            FlightRingCombo.SelectedIndex = i;
            return;
        }
    }

    // if the current ring is non-empty and is not in the list save it to the list
    if (!String.IsNullOrEmpty(ring))
    {
        int index = FlightRingCombo.Items.Count;
        FlightRingCombo.Items.Insert(index, ring);
        FlightRingCombo.SelectedIndex = index;
        return;
    }

    FlightRingCombo.SelectedIndex = 0;
}

private void FlightRingCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var oldRing = SystemUpdateManager.GetFlightRing();
    var newRing = e.AddedItems[0].ToString();
    Debug.WriteLine($"newRing={newRing} oldRing={oldRing}");

    if (oldRing != newRing)
    {
        if (newRing == "None")
        {
            // only set if previous ring was not null or empty
            if (!String.IsNullOrEmpty(oldRing))
            {
                Windows.System.Update.SystemUpdateManager.SetFlightRing(String.Empty);
            }
        }
        else
        {
            Windows.System.Update.SystemUpdateManager.SetFlightRing(newRing);
        }
    }
}

阻止自动重启

若要告知更新服务不允许系统更新,请调用 SystemUpdateManager.UnblockAutomaticRebootAsync (id) 其中 id 是由数字、字母和短划线组成的唯一字符串。 关键代码执行完成后,对于传递到 BlockAutomaticRebootAsync 的每个 ID,代码应调用 SystemUpdateManager.UnblockAutomaticRebootAsync

if (BlockAutoReboot.IsOn)
{
    await SystemUpdateManager.BlockAutomaticRebootAsync(Guid.NewGuid().ToString());
}
else
{
    var ids = SystemUpdateManager.GetAutomaticRebootBlockIds();
    foreach(var id in ids)
    {
        bool unblocked = await SystemUpdateManager.UnblockAutomaticRebootAsync(id);
    }
}

应用程序必须声明 systemManagement 功能。 仅在 Windows 10 IoT 核心版 上受支持。

属性

AttentionRequiredReason

需要用户注意的原因。

DownloadProgress

下载进度百分比。

ExtendedError

扩展的错误信息(如果有)。

InstallProgress

安装进度百分比。

LastErrorInfo

有关上次失败的系统更新的信息。

LastUpdateCheckTime

更新的上次检查时间。

LastUpdateInstallTime

上次安装更新的时间。

State

SystemUpdateManager 的当前状态。

UserActiveHoursEnd

获取用户使用小时结束时间值。

UserActiveHoursMax

获取 UserActiveHoursStartUserActiveHoursEnd 之间允许的最大间隔(以小时为单位)。

UserActiveHoursStart

获取用户使用小时开始时间值。

方法

BlockAutomaticRebootAsync(String)

阻止自动重启更新,直到调用 UnblockAutomaticRebootAsync 或系统策略强制重启。

GetAutomaticRebootBlockIds()

获取自动重启阻止请求的 ID。

GetFlightRing()

获取飞行环。

GetUpdateItems()

获取挂起的更新项的列表。

IsSupported()

指示此设备是否支持此 API。

RebootToCompleteInstall()

如果需要重新启动,则重启设备以完成安装。

SetFlightRing(String)

设置飞行环。

StartCancelUpdates()

如果正在进行任何更新,请开始取消更新。

StartInstall(SystemUpdateStartInstallAction)

启动检测、下载和安装挂起的更新。

TrySetUserActiveHours(TimeSpan, TimeSpan)

尝试设置用户定义的活动时段,在此期间将不允许自动重启更新。

UnblockAutomaticRebootAsync(String)

取消阻止自动更新重启(如果被阻止)。

事件

StateChanged

状态属性更改通知事件。

适用于