Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
A partir de Windows 10, versión 1607, puedes usar métodos de la clase StoreContext en el espacio de nombres Windows.Services.Store para comprobar mediante programación las actualizaciones de paquetes de la aplicación actual desde el Microsoft Store y descargar e instalar los paquetes actualizados. También puede consultar los paquetes marcados como obligatorios en el Centro de partners y deshabilitar la funcionalidad en la aplicación hasta que se instale la actualización obligatoria.
Otros métodos storeContext introducidos en Windows 10, versión 1803 te permiten descargar e instalar actualizaciones de paquetes de forma silenciosa (sin mostrar una interfaz de usuario de notificación al usuario), desinstalar un paquete opcional y obtener información sobre los paquetes de la cola de descarga e instalación de la aplicación.
Estas características te ayudan a mantener tu base de usuarios actualizada automáticamente con la versión más reciente de tu aplicación, paquetes opcionales y servicios relacionados en la Tienda.
Note
Las Windows.Services.Store API requieren la identidad del paquete y funcionan para cualquier aplicación empaquetada con MSIX distribuida a través de la Microsoft Store, incluidas las aplicaciones winUI 3 compiladas con el SDK de Aplicaciones para Windows. Los ejemplos de código de este artículo se escribieron originalmente para UWP. Si las estás adaptando para una aplicación de WinUI 3, reemplaza this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, ...) por DispatcherQueue.GetForCurrentThread().TryEnqueue(...) y reemplaza MessageDialog (que requiere interoperabilidad con HWND en WinUI 3) por ContentDialog, o usa WinRT.Interop.InitializeWithWindow.Initialize para asociar el cuadro de diálogo con el identificador de tu ventana.
Descarga e instalación de actualizaciones de paquetes con el permiso del usuario
En este ejemplo de código se muestra cómo usar el método GetAppAndOptionalStorePackageUpdatesAsync para detectar todas las actualizaciones de paquetes disponibles de store y, a continuación, llamar al método RequestDownloadAndInstallStorePackageUpdatesAsync para descargar e instalar las actualizaciones. Al usar este método para descargar e instalar actualizaciones, el sistema operativo muestra un cuadro de diálogo que solicita el permiso del usuario antes de descargar las actualizaciones.
Note
Estos métodos admiten paquetes obligatorios y opcionales para la aplicación. Los paquetes opcionales son útiles para complementos de contenido descargable (DLC), dividir la aplicación grande para las restricciones de tamaño o para enviar contenido adicional independiente de la aplicación principal. Para obtener permiso para enviar una aplicación que usa paquetes opcionales (incluidos complementos DLC) a la Tienda, consulta Windows soporte técnico para desarrolladores.
En este ejemplo de código se presupone lo siguiente:
- El código se ejecuta en el contexto de una página XAML de UWP (
Windows.UI.Xaml.Controls.Page). Estos ejemplos se escriben para UWP; consulta la NOTA en la parte superior de este artículo para las adaptaciones de WinUI 3. - La página contiene una barra de progreso denominada
downloadProgressBarpara proporcionar el estado de la operación de descarga. - El archivo de código contiene una instrucción using para los espacios de nombres Windows.Services.Store, System.Threading.Tasks y Windows.UI.Popups.
- La aplicación es una aplicación de usuario único que solo se ejecuta en el contexto del usuario que inició la aplicación. Para una aplicación multiusuario, usa el método GetForUser para obtener un objeto StoreContext en lugar del 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();
}
}
}
Note
Para descargar solo (pero no instalar) las actualizaciones del paquete disponibles, use el método RequestDownloadStorePackageUpdatesAsync .
Mostrar información de progreso de descarga e instalación
Al llamar al método RequestDownloadStorePackageUpdatesAsync o RequestDownloadAndInstallStorePackageUpdatesAsync , puede asignar un controlador progress al que se llama una vez por cada paso del proceso de descarga (o descarga e instalación) de cada paquete de esta solicitud. El controlador recibe un objeto StorePackageUpdateStatus que proporciona información sobre el paquete de actualización que generó la notificación de progreso. En el ejemplo anterior se usa el campo PackageDownloadProgress del objeto StorePackageUpdateStatus para mostrar el progreso del proceso de descarga e instalación.
Tenga en cuenta que, al llamar a RequestDownloadAndInstallStorePackageUpdatesAsync para descargar e instalar actualizaciones de paquetes en una sola operación, el campo PackageDownloadProgress aumenta de 0.0 a 0.8 durante el proceso de descarga de un paquete y, a continuación, aumenta de 0.8 a 1.0 durante la instalación. Por lo tanto, si asigna el porcentaje que se muestra en la interfaz de usuario de progreso personalizado directamente al valor del campo PackageDownloadProgress , la interfaz de usuario mostrará 80% cuando finalice la descarga del paquete y el sistema operativo muestra el cuadro de diálogo de instalación. Si desea que la interfaz de usuario de progreso personalizada muestre 100% cuando el paquete se descargue y esté listo para instalarse, puede modificar el código para asignar 100% a la interfaz de usuario de progreso cuando el campo PackageDownloadProgress alcance 0,8.
Descargar e instalar actualizaciones de paquetes de forma silenciosa
A partir de Windows 10, versión 1803, puede usar los métodos TrySilentDownloadStorePackageUpdatesAsync y TrySilentDownloadAndInstallStorePackageUpdatesAsync para descargar e instalar actualizaciones de paquetes de forma silenciosa, sin mostrar una interfaz de usuario de notificación al usuario. Esta operación solo se realizará correctamente si el usuario ha habilitado la opción Actualizar aplicaciones automáticamente en la Tienda y el usuario no está en una red de uso medido. Antes de llamar a estos métodos, primero puede comprobar la propiedad CanSilentlyDownloadStorePackageUpdates para determinar si se cumplen estas condiciones actualmente.
En este ejemplo de código se muestra cómo usar el método GetAppAndOptionalStorePackageUpdatesAsync para detectar todas las actualizaciones de paquetes disponibles y, a continuación, llamar a los métodos TrySilentDownloadStorePackageUpdatesAsync y TrySilentDownloadAndInstallStorePackageUpdatesAsync para descargar e instalar las actualizaciones de forma silenciosa.
En este ejemplo de código se presupone lo siguiente:
- El archivo de código tiene una instrucción using para los espacios de nombres Windows.Services.Store y System.Threading.Tasks.
- La aplicación es una aplicación de usuario único que solo se ejecuta en el contexto del usuario que inició la aplicación. Para una aplicación multiusuario, usa el método GetForUser para obtener un objeto StoreContext en lugar del método GetDefault .
Note
Los métodos IsNowAGoodTimeToRestartApp, RetryDownloadAndInstallLater y RetryInstallLater llamados por el código de este ejemplo son métodos de marcador de posición que están diseñados para implementarse según sea necesario según el diseño de su propia aplicación.
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;
}
}
Actualizaciones de paquetes obligatorias
Al crear un envío de paquete en el Centro de partners para una aplicación que tenga como destino Windows 10, versión 1607 o posterior, puede marcar el paquete como obligatorio y la fecha y hora en que se vuelve obligatorio. Cuando se establece esta propiedad y la aplicación detecta que la actualización del paquete está disponible, la aplicación puede determinar si el paquete de actualización es obligatorio y modificar su comportamiento hasta que se instala la actualización (por ejemplo, la aplicación puede deshabilitar las características).
Note
Microsoft no impone el carácter obligatorio de una actualización de paquete, y el sistema operativo no proporciona una interfaz de usuario que indique a los usuarios que debe instalarse una actualización obligatoria de una aplicación. Los desarrolladores están diseñados para usar la configuración obligatoria para aplicar las actualizaciones de aplicaciones obligatorias en su propio código.
Para marcar un envío de paquete como obligatorio:
- Inicie sesión en el Centro de partners y vaya a la página de información general de la aplicación.
- Haga clic en el nombre del envío que contiene la actualización del paquete que desea que sea obligatoria.
- Vaya a la página Paquetes del envío. Cerca de la parte inferior de esta página, seleccione Hacer que esta actualización sea obligatoria y, a continuación, elija el día y la hora en que la actualización del paquete se convierte en obligatoria. Esta opción se aplica a todos los paquetes del envío.
Para obtener más información, consulte Carga de paquetes de aplicaciones.
Note
Si crea un paquete de vuelo, puede marcar los paquetes como obligatorios mediante una interfaz similar en la página Paquetes del vuelo. En este caso, la actualización obligatoria del paquete solo se aplica a los clientes que forman parte del grupo piloto.
Ejemplo de código para paquetes obligatorios
En el ejemplo de código siguiente se muestra cómo determinar si los paquetes de actualización son obligatorios. Normalmente, si una actualización obligatoria de un paquete no se descarga o instala correctamente, deberías reducir de forma gradual las funcionalidades de la aplicación para el usuario.
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()
{
}
Desinstalación de paquetes opcionales
A partir de Windows 10, versión 1803, puedes usar los métodos RequestUninstallStorePackageAsync o RequestUninstallStorePackageByStoreIdAsync para desinstalar un paquete opcional (incluido un paquete DLC) para la aplicación actual. Por ejemplo, si tiene una aplicación con contenido instalado a través de paquetes opcionales, es posible que quiera proporcionar una interfaz de usuario que permita a los usuarios desinstalar los paquetes opcionales para liberar espacio en disco.
En el ejemplo de código siguiente se muestra cómo llamar a RequestUninstallStorePackageAsync. En este ejemplo se da por supuesto que:
- El archivo de código tiene una instrucción using para los espacios de nombres Windows.Services.Store y System.Threading.Tasks.
- La aplicación es una aplicación de usuario único que solo se ejecuta en el contexto del usuario que inició la aplicación. Para una aplicación multiusuario, usa el método GetForUser para obtener un objeto StoreContext en lugar del método GetDefault .
public async Task UninstallPackage(Windows.ApplicationModel.Package package)
{
if (context == null)
{
context = StoreContext.GetDefault();
}
IAsyncOperation<StoreUninstallStorePackageResult> uninstallOperation =
context.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;
}
}
};
}
Obtener información de la cola de descarga
A partir de Windows 10, versión 1803, puedes usar los métodos GetAssociatedStoreQueueItemsAsync y GetStoreQueueItemsAsync para obtener información sobre los paquetes que se encuentran en la cola de descarga e instalación actual de la Tienda. Estos métodos son útiles si tu aplicación o juego admite paquetes opcionales grandes (incluidos archivos DLL) que pueden tardar horas o días en descargar e instalarse, y quieres controlar correctamente el caso en el que un cliente cierra la aplicación o juego antes de que se complete el proceso de descarga e instalación. Cuando el cliente inicia la aplicación o el juego de nuevo, el código puede usar estos métodos para obtener información sobre el estado de los paquetes que todavía están en la cola de descarga e instalación para que pueda mostrar el estado de cada paquete al cliente.
En el ejemplo de código siguiente se muestra cómo llamar a GetAssociatedStoreQueueItemsAsync para obtener la lista de actualizaciones de paquetes en curso para la aplicación actual y recuperar la información de estado de cada paquete. En este ejemplo se da por supuesto que:
- El archivo de código tiene una instrucción using para los espacios de nombres Windows.Services.Store y System.Threading.Tasks.
- La aplicación es una aplicación de usuario único que solo se ejecuta en el contexto del usuario que inició la aplicación. Para una aplicación multiusuario, usa el método GetForUser para obtener un objeto StoreContext en lugar del método GetDefault .
Note
Los métodos MarkUpdateInProgressInUI, RemoveItemFromUI, MarkInstallCompleteInUI, MarkInstallErrorInUI y MarkInstallPausedInUI llamados por el código de este ejemplo son métodos de marcador de posición que están diseñados para implementarse según sea necesario según el diseño de su propia aplicación.
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;
}
}