Partilhar via


Transfira e instale atualizações de pacotes a partir da Loja

A partir do Windows 10, versão 1607, você pode usar métodos da classe StoreContext no namespace Windows.Services.Store para verificar programaticamente se há atualizações de pacote para o aplicativo atual na Microsoft Store e baixar e instalar os pacotes atualizados. Você também pode consultar pacotes marcados como obrigatórios no Partner Center e desabilitar a funcionalidade em seu aplicativo até que a atualização obrigatória seja instalada.

Os métodos adicionais StoreContext, introduzidos no Windows 10, versão 1803, permitem que o utilizador baixe e instale atualizações de pacotes de forma silenciosa (sem exibir uma interface de notificação para o utilizador), desinstale um pacote opcional e obtenha informações sobre pacotes na fila de download e instalação do seu aplicativo.

Estas funcionalidades ajudam-no a manter automaticamente a sua base de utilizadores atualizada com a versão mais recente da sua aplicação, pacotes opcionais e serviços relacionados na Loja.

Baixar e instalar atualizações de pacotes com a permissão do usuário

Este exemplo de código demonstra como usar o método GetAppAndOptionalStorePackageUpdatesAsync para descobrir todas as atualizações de pacote disponíveis da Loja e, em seguida, chamar o método RequestDownloadAndInstallStorePackageUpdatesAsync para baixar e instalar as atualizações. Ao usar esse método para baixar e instalar atualizações, o sistema operacional exibe uma caixa de diálogo que solicita a permissão do usuário antes de baixar as atualizações.

Observação

Esses métodos suportam pacotes obrigatórios e opcionais para a sua aplicação. Os pacotes opcionais são úteis para complementos de conteúdo para download (DLC), dividindo seu aplicativo grande por restrições de tamanho ou para enviar conteúdo adicional separado do seu aplicativo principal. Para obter permissão para enviar um aplicativo que usa pacotes opcionais (incluindo complementos DLC) para a Loja, consulte de suporte ao desenvolvedor do Windows .

Este exemplo de código pressupõe:

  • O código é executado no contexto de uma Página .
  • O Página contém um ProgressBar chamado para fornecer o status da operação de download.
  • O arquivo de código tem um usando instrução para o Windows.Services.Store, Windows.Threading.Tasks e namespaces Windows.UI.Popups.
  • O aplicativo é um aplicativo de usuário único que é executado somente no contexto do usuário que iniciou o aplicativo. Para uma aplicaçãomultiusuário , use o método GetForUser para obter um objeto StoreContext em vez do método GetDefault.
private StoreContext context = null;

public async Task DownloadAndInstallAllUpdatesAsync()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    // Get the updates that are available.
    IReadOnlyList<StorePackageUpdate> updates =
        await context.GetAppAndOptionalStorePackageUpdatesAsync();

    if (updates.Count > 0)
    {
        // Alert the user that updates are available and ask for their consent
        // to start the updates.
        MessageDialog dialog = new MessageDialog(
            "Download and install updates now? This may cause the application to exit.", "Download and Install?");
        dialog.Commands.Add(new UICommand("Yes"));
        dialog.Commands.Add(new UICommand("No"));
        IUICommand command = await dialog.ShowAsync();

        if (command.Label.Equals("Yes", StringComparison.CurrentCultureIgnoreCase))
        {
            // Download and install the updates.
            IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> downloadOperation =
                context.RequestDownloadAndInstallStorePackageUpdatesAsync(updates);

            // The Progress async method is called one time for each step in the download
            // and installation process for each package in this request.
            downloadOperation.Progress = async (asyncInfo, progress) =>
            {
                await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                () =>
                {
                    downloadProgressBar.Value = progress.PackageDownloadProgress;
                });
            };

            StorePackageUpdateResult result = await downloadOperation.AsTask();
        }
    }
}

Observação

Para baixar (mas não instalar) as atualizações de pacotes disponíveis, use o método RequestDownloadStorePackageUpdatesAsync.

Exibir informações de progresso de download e instalação

Quando chamas o método RequestDownloadStorePackageUpdatesAsync ou o método RequestDownloadAndInstallStorePackageUpdatesAsync, podes atribuir um manipulador de progresso que é chamado uma vez para cada passo no processo de download (ou download e instalação) para cada pacote nesta solicitação. O manipulador recebe um objeto StorePackageUpdateStatus, que fornece informações sobre o pacote de atualização que gerou a notificação de progresso. O exemplo anterior usa o campo PackageDownloadProgress do objeto StorePackageUpdateStatus para mostrar o progresso do processo de transferência e instalação.

Lembre-se de que, quando você chama RequestDownloadAndInstallStorePackageUpdatesAsync para baixar e instalar atualizações de pacote em uma única operação, o campo PackageDownloadProgress aumenta de 0,0 para 0,8 durante o processo de download de um pacote e, em seguida, aumenta de 0,8 para 1,0 durante a instalação. Portanto, se você mapear a porcentagem mostrada em sua interface do usuário de progresso personalizada diretamente para o valor do campo PackageDownloadProgress, sua interface do usuário mostrará 80% quando o download do pacote for concluído e o sistema operacional exibir a caixa de diálogo de instalação. Se quiser que sua interface do usuário de progresso personalizada exiba 100% quando o pacote for baixado e estiver pronto para ser instalado, você poderá modificar seu código para atribuir 100% à sua interface do usuário de progresso quando o campo PackageDownloadProgress atingir 0,8.

Baixe e instale atualizações de pacotes silenciosamente

A partir do Windows 10, versão 1803, pode utilizar os métodos TrySilentDownloadStorePackageUpdatesAsync e TrySilentDownloadAndInstallStorePackageUpdatesAsync para baixar e instalar atualizações de pacotes de forma silenciosa, sem exibir uma interface de notificação para o utilizador. Esta operação só terá êxito se o utilizador tiver ativado a definição Atualizar aplicações automaticamente na Loja e se o utilizador não estiver numa rede com tráfego limitado. Antes de chamar esses métodos, pode primeiro verificar a propriedade CanSilentlyDownloadStorePackageUpdates para determinar se essas condições são atendidas no momento.

Este exemplo de código demonstra como usar o método GetAppAndOptionalStorePackageUpdatesAsync para descobrir todas as atualizações de pacote disponíveis e, em seguida, chamar os métodos TrySilentDownloadStorePackageUpdatesAsync e TrySilentDownloadAndInstallStorePackageUpdatesAsync para baixar e instalar as atualizações silenciosamente.

Este exemplo de código pressupõe:

  • O ficheiro de código contém uma instrução de usando para os namespaces Windows.Services.Store e System.Threading.Tasks.
  • O aplicativo é um aplicativo de usuário único que é executado somente no contexto do usuário que iniciou o aplicativo. Para uma aplicaçãomultiusuário , use o método GetForUser para obter um objeto StoreContext em vez do método GetDefault.

Observação

Os métodos IsNowAGoodTimeToRestartApp, RetryDownloadAndInstallLatere RetryInstallLater chamados pelo código neste exemplo são métodos de espaço reservado que devem ser implementados conforme necessário de acordo com o design do seu próprio aplicativo.

private StoreContext context = null;

public async Task DownloadAndInstallAllUpdatesInBackgroundAsync()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    // Get the updates that are available.
    IReadOnlyList<StorePackageUpdate> storePackageUpdates =
        await context.GetAppAndOptionalStorePackageUpdatesAsync();

    if (storePackageUpdates.Count > 0)
    {

        if (!context.CanSilentlyDownloadStorePackageUpdates)
        {
            return;
        }

        // Start the silent downloads and wait for the downloads to complete.
        StorePackageUpdateResult downloadResult =
            await context.TrySilentDownloadStorePackageUpdatesAsync(storePackageUpdates);

        switch (downloadResult.OverallState)
        {
            case StorePackageUpdateState.Completed:
                // The download has completed successfully. At this point, confirm whether your app
                // can restart now and then install the updates (for example, you might only install
                // packages silently if your app has been idle for a certain period of time). The
                // IsNowAGoodTimeToRestartApp method is not implemented in this example, you should
                // implement it as needed for your own app.
                if (IsNowAGoodTimeToRestartApp())
                {
                    await InstallUpdate(storePackageUpdates);
                }
                else
                {
                    // Retry/reschedule the installation later. The RetryInstallLater method is not  
                    // implemented in this example, you should implement it as needed for your own app.
                    RetryInstallLater();
                    return;
                }
                break;
            // If the user cancelled the download or you can't perform the download for some other
            // reason (for example, Wi-Fi might have been turned off and the device is now on
            // a metered network) try again later. The RetryDownloadAndInstallLater method is not  
            // implemented in this example, you should implement it as needed for your own app.
            case StorePackageUpdateState.Canceled:
            case StorePackageUpdateState.ErrorLowBattery:
            case StorePackageUpdateState.ErrorWiFiRecommended:
            case StorePackageUpdateState.ErrorWiFiRequired:
            case StorePackageUpdateState.OtherError:
                RetryDownloadAndInstallLater();
                return;
            default:
                break;
        }
    }
}

private async Task InstallUpdate(IReadOnlyList<StorePackageUpdate> storePackageUpdates)
{
    // Start the silent installation of the packages. Because the packages have already
    // been downloaded in the previous method, the following line of code just installs
    // the downloaded packages.
    StorePackageUpdateResult downloadResult =
        await context.TrySilentDownloadAndInstallStorePackageUpdatesAsync(storePackageUpdates);

    switch (downloadResult.OverallState)
    {
        // If the user cancelled the installation or you can't perform the installation  
        // for some other reason, try again later. The RetryInstallLater method is not  
        // implemented in this example, you should implement it as needed for your own app.
        case StorePackageUpdateState.Canceled:
        case StorePackageUpdateState.ErrorLowBattery:
        case StorePackageUpdateState.OtherError:
            RetryInstallLater();
            return;
        default:
            break;
    }
}

Atualizações obrigatórias de pacotes

Ao criar um envio de pacote no Partner Center para um aplicativo destinado ao Windows 10, versão 1607 ou posterior, você pode marcar o pacote como obrigatório e a data e hora em que ele se torna obrigatório. Quando essa propriedade é definida e seu aplicativo descobre que a atualização de pacote está disponível, seu aplicativo pode determinar se o pacote de atualização é obrigatório e alterar seu comportamento até que a atualização seja instalada (por exemplo, seu aplicativo pode desabilitar recursos).

Observação

O status obrigatório de uma atualização de pacote não é imposto pela Microsoft e o sistema operacional não fornece uma interface do usuário para indicar aos usuários que uma atualização obrigatória de aplicativo deve ser instalada. Os desenvolvedores devem usar a configuração obrigatória para impor atualizações obrigatórias de aplicativos em seu próprio código.

Para marcar o envio de um pacote como obrigatório:

  1. Entre no Partner Center e navegue até a página de visão geral do seu aplicativo.
  2. Clique no nome do envio que contém a atualização do pacote que você deseja tornar obrigatória.
  3. Navegue até a página Pacotes para a submissão. Perto da parte inferior desta página, selecione Tornar esta atualização obrigatória e, em seguida, escolha o dia e a hora em que a atualização do pacote se torna obrigatória. Esta opção se aplica a todos os pacotes UWP no envio.

Para obter mais informações, consulte Carregar pacotes de aplicações.

Observação

Se você criar um pacote de voos, poderá marcar os pacotes como obrigatórios usando uma interface do usuário semelhante na página Pacotes do voo. Neste caso, a atualização obrigatória do pacote aplica-se apenas aos clientes que fazem parte do grupo de voos.

Exemplo de código para pacotes obrigatórios

O exemplo de código a seguir demonstra como determinar se quaisquer pacotes de atualização são obrigatórios. Normalmente, deve reduzir gradualmente a qualidade da experiência do aplicativo para o utilizador caso uma atualização de pacote obrigatória não seja descarregada ou instalada com sucesso.

private StoreContext context = null;

// Downloads and installs package updates in separate steps.
public async Task DownloadAndInstallAllUpdatesAsync()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }  

    // Get the updates that are available.
    IReadOnlyList<StorePackageUpdate> updates =
        await context.GetAppAndOptionalStorePackageUpdatesAsync();

    if (updates.Count != 0)
    {
        // Download the packages.
        bool downloaded = await DownloadPackageUpdatesAsync(updates);

        if (downloaded)
        {
            // Install the packages.
            await InstallPackageUpdatesAsync(updates);
        }
    }
}

// Helper method for downloading package updates.
private async Task<bool> DownloadPackageUpdatesAsync(IEnumerable<StorePackageUpdate> updates)
{
    bool downloadedSuccessfully = false;

    IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> downloadOperation =
        this.context.RequestDownloadStorePackageUpdatesAsync(updates);

    // The Progress async method is called one time for each step in the download process for each
    // package in this request.
    downloadOperation.Progress = async (asyncInfo, progress) =>
    {
        await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        () =>
        {
            downloadProgressBar.Value = progress.PackageDownloadProgress;
        });
    };

    StorePackageUpdateResult result = await downloadOperation.AsTask();

    switch (result.OverallState)
    {
        case StorePackageUpdateState.Completed:
            downloadedSuccessfully = true;
            break;
        default:
            // Get the failed updates.
            var failedUpdates = result.StorePackageUpdateStatuses.Where(
                status => status.PackageUpdateState != StorePackageUpdateState.Completed);

            // See if any failed updates were mandatory
            if (updates.Any(u => u.Mandatory && failedUpdates.Any(
                failed => failed.PackageFamilyName == u.Package.Id.FamilyName)))
            {
                // At least one of the updates is mandatory. Perform whatever actions you
                // want to take for your app: for example, notify the user and disable
                // features in your app.
                HandleMandatoryPackageError();
            }
            break;
    }

    return downloadedSuccessfully;
}

// Helper method for installing package updates.
private async Task InstallPackageUpdatesAsync(IEnumerable<StorePackageUpdate> updates)
{
    IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> installOperation =
        this.context.RequestDownloadAndInstallStorePackageUpdatesAsync(updates);

    // The package updates were already downloaded separately, so this method skips the download
    // operation and only installs the updates; no download progress notifications are provided.
    StorePackageUpdateResult result = await installOperation.AsTask();

    switch (result.OverallState)
    {
        case StorePackageUpdateState.Completed:
            break;
        default:
            // Get the failed updates.
            var failedUpdates = result.StorePackageUpdateStatuses.Where(
                status => status.PackageUpdateState != StorePackageUpdateState.Completed);

            // See if any failed updates were mandatory
            if (updates.Any(u => u.Mandatory && failedUpdates.Any(failed => failed.PackageFamilyName == u.Package.Id.FamilyName)))
            {
                // At least one of the updates is mandatory, so tell the user.
                HandleMandatoryPackageError();
            }
            break;
    }
}

// Helper method for handling the scenario where a mandatory package update fails to
// download or install. Add code to this method to perform whatever actions you want
// to take, such as notifying the user and disabling features in your app.
private void HandleMandatoryPackageError()
{
}

Desinstalar pacotes opcionais

A partir do Windows 10, versão 1803, você pode usar o RequestUninstallStorePackageAsync ou métodos de RequestUninstallStorePackageByStoreIdAsync para desinstalar um de pacote opcional (incluindo um pacote DLC) para o aplicativo atual. Por exemplo, se você tiver um aplicativo com conteúdo instalado por meio de pacotes opcionais, convém fornecer uma interface do usuário que permita aos usuários desinstalar os pacotes opcionais para liberar espaço em disco.

O exemplo de código a seguir demonstra como chamar RequestUninstallStorePackageAsync. Este exemplo pressupõe:

  • O ficheiro de código contém uma instrução de usando para os namespaces Windows.Services.Store e System.Threading.Tasks.
  • O aplicativo é um aplicativo de usuário único que é executado somente no contexto do usuário que iniciou o aplicativo. Para uma aplicaçãomultiusuário , use o método GetForUser para obter um objeto StoreContext em vez do método GetDefault.
public async Task UninstallPackage(Windows.ApplicationModel.Package package)
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    var storeContext = StoreContext.GetDefault();
    IAsyncOperation<StoreUninstallStorePackageResult> uninstallOperation =
        storeContext.RequestUninstallStorePackageAsync(package);

    // At this point, you can update your app UI to show that the package
    // is installing.

    uninstallOperation.Completed += (asyncInfo, status) =>
    {
        StoreUninstallStorePackageResult result = uninstallOperation.GetResults();
        switch (result.Status)
        {
            case StoreUninstallStorePackageStatus.Succeeded:
                {
                    // Update your app UI to show the package as uninstalled.
                    break;
                }
            default:
                {
                    // Update your app UI to show that the package uninstall failed.
                    break;
                }
        }
    };
}

Obter informações sobre a fila de download

A partir do Windows 10, versão 1803, pode utilizar os métodos GetAssociatedStoreQueueItemsAsync e GetStoreQueueItemsAsync para obter informações sobre os pacotes que estão na fila de download e instalação atual da Microsoft Store. Esses métodos são úteis se seu aplicativo ou jogo suportar grandes pacotes opcionais (incluindo DLCs) que podem levar horas ou dias para baixar e instalar, e você quiser lidar normalmente com o caso em que um cliente fecha seu aplicativo ou jogo antes que o processo de download e instalação seja concluído. Quando o cliente inicia seu aplicativo ou jogo novamente, seu código pode usar esses métodos para obter informações sobre o estado dos pacotes que ainda estão na fila de download e instalação, para que você possa exibir o status de cada pacote para o cliente.

O exemplo de código a seguir demonstra como chamar GetAssociatedStoreQueueItemsAsync para obter a lista de atualizações de pacote em andamento para o aplicativo atual e recuperar informações de status para cada pacote. Este exemplo pressupõe:

  • O ficheiro de código contém uma instrução de usando para os namespaces Windows.Services.Store e System.Threading.Tasks.
  • O aplicativo é um aplicativo de usuário único que é executado somente no contexto do usuário que iniciou o aplicativo. Para uma aplicaçãomultiusuário , use o método GetForUser para obter um objeto StoreContext em vez do método GetDefault.

Observação

Os métodos MarkUpdateInProgressInUI, RemoveItemFromUI, MarkInstallCompleteInUI, MarkInstallErrorInUIe MarkInstallPausedInUI, que o código neste exemplo chama, são métodos de espaço reservado que devem ser implementados conforme necessário, conforme o design do seu próprio aplicativo.

private StoreContext context = null;

private async Task GetQueuedInstallItemsAndBuildInitialStoreUI()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    // Get the Store packages in the install queue.
    IReadOnlyList<StoreQueueItem> storeUpdateItems = await context.GetAssociatedStoreQueueItemsAsync();

    foreach (StoreQueueItem storeItem in storeUpdateItems)
    {
        // In this example we only care about package updates.
        if (storeItem.InstallKind != StoreQueueItemKind.Update)
            continue;

        StoreQueueItemStatus currentStatus = storeItem.GetCurrentStatus();
        StoreQueueItemState installState = currentStatus.PackageInstallState;
        StoreQueueItemExtendedState extendedInstallState =
            currentStatus.PackageInstallExtendedState;

        // Handle the StatusChanged event to display current status to the customer.
        storeItem.StatusChanged += StoreItem_StatusChanged;

        switch (installState)
        {
            // Download and install are still in progress, so update the status for this  
            // item and provide the extended state info. The following methods are not
            // implemented in this example; you should implement them as needed for your
            // app's UI.
            case StoreQueueItemState.Active:
                MarkUpdateInProgressInUI(storeItem, extendedInstallState);
                break;
            case StoreQueueItemState.Canceled:
                RemoveItemFromUI(storeItem);
                break;
            case StoreQueueItemState.Completed:
                MarkInstallCompleteInUI(storeItem);
                break;
            case StoreQueueItemState.Error:
                MarkInstallErrorInUI(storeItem);
                break;
            case StoreQueueItemState.Paused:
                MarkInstallPausedInUI(storeItem, installState, extendedInstallState);
                break;
        }
    }
}

private void StoreItem_StatusChanged(StoreQueueItem sender, object args)
{
    StoreQueueItemStatus currentStatus = sender.GetCurrentStatus();
    StoreQueueItemState installState = currentStatus.PackageInstallState;
    StoreQueueItemExtendedState extendedInstallState = currentStatus.PackageInstallExtendedState;

    switch (installState)
    {
        // Download and install are still in progress, so update the status for this  
        // item and provide the extended state info. The following methods are not
        // implemented in this example; you should implement them as needed for your
        // app's UI.
        case StoreQueueItemState.Active:
            MarkUpdateInProgressInUI(sender, extendedInstallState);
            break;
        case StoreQueueItemState.Canceled:
            RemoveItemFromUI(sender);
            break;
        case StoreQueueItemState.Completed:
            MarkInstallCompleteInUI(sender);
            break;
        case StoreQueueItemState.Error:
            MarkInstallErrorInUI(sender);
            break;
        case StoreQueueItemState.Paused:
            MarkInstallPausedInUI(sender, installState, extendedInstallState);
            break;
    }
}